分类 Docker & K8S 下的文章

安装MySQL

docker run -p 3306:3306 --name mysql \
-v /idata/mysql/log:/var/log/mysql \
-v /idata/mysql/data:/var/lib/mysql \
-v /idata/mysql/conf:/etc/mysql \
-e MYSQL_ROOT_PASSWORD=root \
-d mysql:5.7

docker exec -it mysql mysql -uroot -proot
#配置MySQL主从复制 
#创建master
docker run -p 3306:3306 --name mysql-master \
-v /idata/mysql/log:/var/log/mysql \
-v /idata/mysql/data:/var/lib/mysql \
-v /idata/mysql/conf:/etc/mysql \
-e MYSQL_ROOT_PASSWORD=root \
-d mysql:5.7
##配置文件
vim /idata/mysql/conf/my.cnf

[client]
default-character-set=utf8
 
[mysql]
default-character-set=utf8
 
[mysqld]
init_connect='SET collation_connection = utf8_unicode_ci'
init_connect='SET NAMES utf8'
character-set-server=utf8
collation-server=utf8_unicode_ci
skip-character-set-client-handshake
skip-name-resolve

server_id=1
log-bin=mysql-bin
read-only=0
binlog-do-db=icoding_test

replicate-ignore-db=mysql
replicate-ignore-db=sys
replicate-ignore-db=information_schema
replicate-ignore-db=performance_schema

#创建Slaver,和master一致,配置文件修改如下即可
server_id=2
log-bin=mysql-bin
read-only=1
binlog-do-db=icoding_test

replicate-ignore-db=mysql
replicate-ignore-db=sys
replicate-ignore-db=information_schema
replicate-ignore-db=performance_schema

#配置matser
1、添加用来同步的用户
       GRANT REPLICATION SLAVE ON *.* to 'backup'@'%' identified by '123456';
2、查看master状态
   show master status\G;
 
#配置slaver
1、change master to master_host='mysql-master',master_user='backup',master_password='123456',master_log_file='mysql-bin.000003',master_log_pos=0,master_port=3306;
2、start slave;
3、show slave status\G;

安装Redis

mkdir -p /idata/redis/conf
touch /idata/redis/conf/redis.conf

docker run -p 6379:6379 --name redis -v /idata/redis/data:/data \
-v /idata/redis/conf:/etc/redis \
-d redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf

redis 自描述文件:
https://raw.githubusercontent.com/antirez/redis/4.0/redis.conf

#安装redis-cluster;3主3从方式,从为了同步备份,主进行slot数据分片
##单机情况下可以这样做。
## cluster-announce-ip 192.168.56.10 为自己服务器的ip
for port in $(seq 7001 7006); \
do \
mkdir -p /mydata/redis/node-${port}/conf
touch /mydata/redis/node-${port}/conf/redis.conf
cat << EOF >/mydata/redis/node-${port}/conf/redis.conf
port ${port}
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
cluster-announce-ip 172.26.65.131 
cluster-announce-port ${port}
cluster-announce-bus-port 1${port}
appendonly yes
EOF
docker run -p ${port}:${port} -p 1${port}:1${port} --name redis-${port} \
-v /mydata/redis/node-${port}/data:/data \
-v /mydata/redis/node-${port}/conf/redis.conf:/etc/redis/redis.conf \
-d redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf; \
done
docker stop $(docker ps -a |grep redis-700 | awk '{ print $1}')
docker rm $(docker ps -a |grep redis-700 | awk '{ print $1}')

##建立集群
docker exec -it redis-7001 /bin/sh
redis-cli --cluster create 172.26.65.131:7001 172.26.65.131:7002 172.26.65.131:7003 172.26.65.131:7004 172.26.65.131:7005 172.26.65.131:7006 --cluster-replicas 1

redis-cli -c -h 192.168.56.10 -p 7006  # -c方式连接
cluster info ,cluster node;测试
#模拟网络分离的
docker network create redis --subnet 172.38.0.0/16
for port in $(seq 1 6); \
do \
mkdir -p /mydata/redis/node-${port}/conf
touch /mydata/redis/node-${port}/conf/redis.conf
cat << EOF >/mydata/redis/node-${port}/conf/redis.conf
port 6379
bind 0.0.0.0
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
cluster-announce-ip 172.38.0.1${port}
cluster-announce-port 6379
cluster-announce-bus-port 16379
appendonly yes
EOF
done



docker run -p 637${port}:6379 -p 1637${port}:16379 --name redis-${port} \
-v /mydata/redis/node-${port}/data:/data \
-v /mydata/redis/node-${port}/conf/redis.conf:/etc/redis/redis.conf \
-d --net redis --ip 192.168.0.1${port} redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf; \


docker run -p 6371:6379 -p 16371:16379 --name redis-1 \
-v /mydata/redis/node-1/data:/data \
-v /mydata/redis/node-1/conf/redis.conf:/etc/redis/redis.conf \
-d --net redis --ip 172.38.0.11 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf


docker run -p 6376:6379 -p 16376:16379 --name redis-6 \
-v /mydata/redis/node-6/data:/data \
-v /mydata/redis/node-6/conf/redis.conf:/etc/redis/redis.conf \
-d --net redis --ip 172.38.0.16 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf

docker exec -it redis-1 /bin/sh
redis-cli --cluster create 172.38.0.11:6379 172.38.0.12:6379 172.38.0.13:6379 172.38.0.14:6379 172.38.0.15:6379 172.38.0.16:6379 --cluster-replicas 1

安装ElasticSearch

mkdir -p /idata/es/config
mkdir -p /idata/es/data
echo "http.host: 0.0.0.0" >> /idata/es/config/elasticsearch.yml
chmod -R 777 /idata/es/ #保证权限
docker run --name elasticsearch -p 9200:9200 -p 9300:9300 \
-e "discovery.type=single-node" \
-e ES_JAVA_OPTS="-Xms64m -Xmx512m" \
-v /idata/es/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml \
-v /idata/es/data:/usr/share/elasticsearch/data \
-v /idata/es/plugins:/usr/share/elasticsearch/plugins \
-d elasticsearch:7.4.2
docker run --name kibana -e ELASTICSEARCH_HOSTS=http://192.168.0.10:9200 -p 5601:5601 \
-d kibana:7.4.2
#安装Es集群
所有之前先运行:sysctl -w vm.max_map_count=262144
我们只是测试,所以临时修改。永久修改使用下面
#防止 JVM 报错
echo vm.max_map_count=262144 >> /etc/sysctl.conf
sysctl -p

##############3-master##########################
for port in $(seq 1 3); \
do \
mkdir -p /mydata/elasticsearch/master-${port}/config
mkdir -p /mydata/elasticsearch/master-${port}/data
chmod -R 777 /mydata/elasticsearch/master-${port}
cat << EOF >/mydata/elasticsearch/master-${port}/config/elasticsearch.yml
cluster.name: my-es #集群的名称,同一个集群该值必须设置成相同的
node.name: es-master-${port} #该节点的名字
node.master: true #该节点有机会成为 master 节点
node.data: false #该节点可以存储数据
network.host: 0.0.0.0
http.host: 0.0.0.0 #所有 http 均可访问
http.port: 920${port}
transport.tcp.port: 930${port}
discovery.zen.ping_timeout: 10s #设置集群中自动发现其他节点时 ping 连接的超时时间
discovery.seed_hosts: ["172.18.12.21:9301", "172.18.12.22:9302", "172.18.12.23:9303"] #设置集群中的 Master 节点的初始列表,可以通过这些节点来自动发现其他新加入集群的节点,es7的新增配置;
cluster.initial_master_nodes: ["172.18.12.21"] #新集群初始时的候选主节点,es7 的新增配置
EOF
docker run --name elasticsearch-node-${port} \ -p 920${port}:920${port} -p 930${port}:930${port} \ --network=mynet --ip 172.18.12.2${port} \
-e ES_JAVA_OPTS="-Xms300m -Xmx300m" \ -v
/mydata/elasticsearch/master-${port}/config/elasticsearch.yml:/usr/share/elasticsearch/config/el
asticsearch.yml \ -v /mydata/elasticsearch/master-${port}/data:/usr/share/elasticsearch/data \ -v /mydata/elasticsearch/master-${port}/plugins:/usr/share/elasticsearch/plugins \ -d elasticsearch:7.4.2
done




#######################3-node#######################
for port in $(seq 4 6); \
do \
mkdir -p /mydata/elasticsearch/node-${port}/config
mkdir -p /mydata/elasticsearch/node-${port}/data
chmod -R 777 /mydata/elasticsearch/node-${port}
cat << EOF >/mydata/elasticsearch/node-${port}/config/elasticsearch.yml
cluster.name: my-es #集群的名称,同一个集群该值必须设置成相同的
node.name: es-node-${port} #该节点的名字
node.master: false #该节点有机会成为 master 节点
node.data: true #该节点可以存储数据
network.host: 0.0.0.0
#network.publish_host: 192.168.56.10 #互相通信 ip,要设置为本机可被外界访问的 ip,否则
无法通信
http.host: 0.0.0.0 #所有 http 均可访问
http.port: 920${port}
transport.tcp.port: 930${port}
#discovery.zen.minimum_master_nodes: 2 #设置这个参数来保证集群中的节点可以知道其
它 N 个有 master 资格的节点。官方推荐(N/2)+1
discovery.zen.ping_timeout: 10s #设置集群中自动发现其他节点时 ping 连接的超时时间
discovery.seed_hosts: ["172.18.12.21:9301", "172.18.12.22:9302", "172.18.12.23:9303"] #设置集群中的 Master 节点的初始列表,可以通过这些节点来自动发现其他新加入集群的节点,es7
的新增配置
cluster.initial_master_nodes: ["172.18.12.21"] #新集群初始时的候选主节点,es7 的新增配置
EOF
docker run --name elasticsearch-node-${port} \ -p 920${port}:920${port} -p 930${port}:930${port} \ --network=mynet --ip 172.18.12.2${port} \ -e ES_JAVA_OPTS="-Xms300m -Xmx300m" \ -v
/mydata/elasticsearch/node-${port}/config/elasticsearch.yml:/usr/share/elasticsearch/config/ela
sticsearch.yml \ -v /mydata/elasticsearch/node-${port}/data:/usr/share/elasticsearch/data \ -v /mydata/elasticsearch/node-${port}/plugins:/usr/share/elasticsearch/plugins \ -d elasticsearch:7.4.2
done

##检查
_nodes/process?pretty 查看节点状况
_cluster/stats?pretty 查看集群状态
_cluster/health?pretty 查看集群健康状况
_cat/nodes 查看各个节点信息
- discovery.seed_hosts=es01,es03
- cluster.initial_master_nodes=es01,es02,es03
#还可以只开放一个实例端口.其他的都用集群内访问就可以啦。
#也可以使用自定义Docker网络的方式
docker network create --driver bridge --subnet 172.21.0.0/16 --gateway 172.21.0.1 mynet
#运行容器的时候,使用 --ip --network指定网络

安装Nginx

  • 随便启动一个 nginx 实例, 只是为了复制出配置

    docker run -p 80:80 --name nginx -d nginx:1.10

  • 将容器内的配置文件拷贝到当前目录:

    • mkdir -p /idata/nginx/conf
    • docker container cp nginx:/etc/nginx/. /idata/nginx/conf
  • 创建新的 nginx; 执行以下命令
    docker run -p 80:80 --name nginx \
    -v /idata/nginx/html:/usr/share/nginx/html \
    -v /idata/nginx/logs:/var/log/nginx \
    -v /idata/nginx/conf:/etc/nginx \
    -d nginx:1.10
  • 给 nginx 的 html 下面放的所有资源可以直接访问;

安装RabbitMQ

#简单安装
docker run -d --name rabbitmq -p 5671:5671 -p 5672:5672 -p 4369:4369 -p
25672:25672 -p 15671:15671 -p 15672:15672 -v /idata/rabbitmq:/var/lib/rabbitmq rabbitmq:management

4369, 25672 (Erlang发现&集群端口)
5672, 5671 (AMQP端口)
15672 (web管理后台端口)
61613, 61614 (STOMP协议端口)
1883, 8883 (MQTT协议端口)
https://www.rabbitmq.com/networking.html
#安装RabbitMQ镜像集群
#三台机器分别运行
mkdir -p /idata/rabbitmq
vi /idata/rabbitmq/hosts
192.168.0.48 rabbit1 rabbit1
192.168.0.47 rabbit2 rabbit2
192.168.0.46 rabbit3 rabbit3

#注意修改每个-h 参数,修改为正确的hostname
docker run -d --name rabbitmq -h rabbit1 -v /idata/rabbitmq:/var/lib/rabbitmq -v /idata/rabbitmq/hosts:/etc/hosts -p 5671:5671 -p 5672:5672 -p 4369:4369 -p 25672:25672 -p 15671:15671 -p 15672:15672 -e RABBITMQ_ERLANG_COOKIE='icodingedu' rabbitmq:management
#上面这种方式匹配主机名适用于完全分布式情况,单机模拟集群,大家觉得还有更好的方式吗?(请使用自定义网络的方式)

#RABBITMQ_ERLANG_COOKIE 节点认证作用,部署集成时 需要同步该值

#节点加入集群
#初始化第一个节点
docker exec -it rabbitmq /bin/bash
rabbitmqctl stop_app
rabbitmqctl reset
rabbitmqctl start_app
Exit

#设置集群内的其他节点
docker exec -it rabbitmq /bin/bash
rabbitmqctl stop_app
rabbitmqctl reset
rabbitmqctl join_cluster --ram rabbit@rabbit1 #master的ip
rabbitmqctl start_app
exit

#实现镜像集群
#进入主节点进行操作
docker exec -it rabbitmq bash
rabbitmqctl set_policy -p / ha "^" '{"ha-mode":"all","ha-sync-mode":"automatic"}'

可以使用 rabbitmqctl list_policies -p /;查看vhost/下面的所有policy
在cluster中任意节点启用策略,策略会自动同步到集群节点
rabbitmqctl set_policy -p / ha-all "^" '{"ha-mode":"all"}'
策略模式 all 即复制到所有节点,包含新增节点,策略正则表达式为 “^” 表示所有匹配所有队列名称。“^hello”表示只匹配名为hello开始的队列

端口映射

docker create -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 --name hello-mysql mysql:5.7

-p HostPort:ContainerPort | IP:HostPort:ContainerPort | HostPort:ContainerPort

  • 查看端口映射

    • docker port hello-mysql

容器互联

--link name:alias,name连接容器的名称,alias连接的别名

场景:我们无需暴露mysql的情况下,让web应用使用mysql;

docker run -d -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:5.7
docker run -d --link mysql01:mysql --name tomcat tomcat:7

docker exec -it tomcat bash
cat /etc/hosts

使用Docker过程中,往往需要对数据进行持久化,或者多个容器之间进行数据共享,这就需要我们熟悉容器的数据管理操作

容器中管理数据主要的两种方式:

  • 数据卷(Data Volumes):容器内数据直接映射到本地主机环境
  • 数据卷容器(Data Volumes Containers):使用特定容器维护数据

数据卷

将主机操作系统目录直接映射进容器,类似于Linux中的mount。数据卷很好的解耦了容器应用和数据。对数据卷内数据的操作(无论是在本地主机还是容器内),都会立即生效。

docker run -d -p 3307:3306 -v /my/custom:/etc/mysql/conf.d \
-v /my/own/datadir:/var/lib/mysql --restart always --name mysql01 mysql:5.7

-v hostDir:containerDir:hostDir不存在会自动创建,默认权限是rw,也可以改为ro,这样容器内部就无法对数据卷的数据进行修改了。

docker run -d -p 3307:3306 -v /my/custom:/etc/mysql/conf.d:ro \
-v /my/own/datadir:/var/lib/mysql --restart always --name mysql01 mysql:5.7
#数据卷创建
docker volume create [OPTIONS] [VOLUME]
docker volume create hello
docker run -d -p 3307:3306 -v hello:/etc/mysql/conf.d \
-v /my/own/datadir:/var/lib/mysql --restart always --name mysql01 mysql:5.7

#数据卷列表
docker volume ls

#数据卷详情
docker volume inspect hello
[
    {
        "CreatedAt": "2020-04-08T06:43:08Z",
        "Driver": "local",
        "Labels": {},
        "Mountpoint": "/var/lib/docker/volumes/hello/_data",
        "Name": "hello",
        "Options": {},
        "Scope": "local"
    }
]
#docker cp 用于容器与主机之间的数据拷贝
docker cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH|-
docker cp [OPTIONS] SRC_PATH|- CONTAINER:DEST_PATH
  • SRC_PATH 指定为一个文件

    • DEST_PATH 不存在:文件名为 DEST_PATH,内容为SRC的内容
    • DEST_PATH 不存在并且以 / 结尾:报错
    • DEST_PATH 存在并且是文件:目标文件内容被替换为SRC_PATH的文件内容。
    • DEST_PATH 存在并且是目录:文件复制到目录内,文件名为SRC_PATH指定的名字
  • SRC_PATH 指定为一个目录

    • DEST_PATH 不存在:DEST_PATH创建文件夹,复制源文件夹内的所有内容
    • DEST_PATH 存在是文件:报错
    • DEST_PATH 存在是目录

      • SRC_PATH 不以 /. 结束:源文件夹复制到目标里面
      • SRC_PATH/. 结束:源文件夹里面的内容复制到目标里面

      自动创建文件夹不会做递归。把父文件夹做好

数据卷容器

如果需要在多个容器之间共享一些持续更新的数据,最简单的方式是使用数据卷容器。数据卷容器也是一个容器,但他专门用来提供数据卷供其他容器挂载。

docker run -it -v /idata --name idata ubuntu

docker run -it --volumes-from idata --name d01 ubuntu
docker run -it --volumes-from idata --name d02 ubuntu
#使用--volumes-from参数所挂载的数据卷容器本身不需要保持在运行状态

数据卷的用法细节

docker run -d -P --name nginx nginx
#方便修改nginx的配置和html页面等
#容器中 /usr/share/nginx/html
#容器中 /etc/nginx

##参照一下各种写法
# hostPath:containerPath
docker run -d -P --name nginx -v /opt/nginx/html:/usr/share/nginx/html nginx;
    #为什么看到的是403而不是index页面内容。原来容器里面变为空了?主机的内容复制到容器中,导致,容器同步到了主机的空文件夹。
    #特别是配置问津,必须提前保证我们主机挂载的目录里面提前有内容。
docker run -d -P --name nginx -v /opt/nginx:/etc/nginx nginx
    #为什么docker ps看不到;出错了。open() "/etc/nginx/nginx.conf" failed (2: No such file or directory) nginx: [emerg] open() "/etc/nginx/nginx.conf" failed (2: No such file or directory)
#我就想自定义挂载路径,并且把他们挂载出来?
    # 1、复制容器的文件
        docker cp
        1、启动一个nginx,先不挂载。
        2、docker cp把运行中的nginx的内容复制出来
            Usage:    docker cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH|-
                    docker cp [OPTIONS] SRC_PATH|- CONTAINER:DEST_PATH
        docker cp nginx:/usr/share/nginx/html /opt/hahanginx
        nginx:/usr/share/nginx/html/. 把html里面的内容复制到 /opt/hahanginx
        nginx:/usr/share/nginx/html 把html文件夹复制到 /opt/hahanginx
        
        
        完整过程
        mkdir /opt/nginx
        docker cp nginx:/usr/share/nginx/html /opt/nginx 复制html
        docker cp nginx:/etc/nginx/. /opt/nginx/conf
        docker run -d -P --name nginx -v /opt/nginx/conf:/etc/nginx -v /opt/nginx/html:/usr/share/nginx/html nginx
        
# 匿名卷方式volume,挂载任意目录
docker run -d -P --name nginx02 -v 容器路径
eg:
docker run -d -P --name nginx02 -v /usr/share/nginx/html -v /etc/nginx nginx
想要知道到底迎合到主机的哪里了?
docker inspect nginx02.
"Mounts": [
            {
                "Type": "volume",
                "Name": "9f4f8ac4c9cd9cb77df7a5386a5b68520c98ea1bb28e26b6593255c1d0ff9cdf",
                "Source": "/var/lib/docker/volumes/9f4f8ac4c9cd9cb77df7a5386a5b68520c98ea1bb28e26b6593255c1d0ff9cdf/_data",
                "Destination": "/usr/share/nginx/html",
                "Driver": "local",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            },
            {
                "Type": "volume",
                "Name": "68afef2bf4979e2c9369f6eb68f8a94adc61e63d3a1fb3dad7469e243442cf32",
                "Source": "/var/lib/docker/volumes/68afef2bf4979e2c9369f6eb68f8a94adc61e63d3a1fb3dad7469e243442cf32/_data",
                "Destination": "/etc/nginx",
                "Driver": "local",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            }
        ],

#匿名挂载的缺点?不好维护。 docker volume可以维护他们
docker volume ls

#具名挂载。有卷。如果有可视化界面。我们就知道卷是干嘛,就不乱删除了。
#创建好的卷,会自动的和容器中需要挂载的这个文件夹做好同步。
docker volume create 卷名字, 创建一个卷。/var/lib/docker/volumes/自定义的卷名/_data
docker run -d -P --name nginx03 -v nginxconf:/etc/nginx -v nginxhtml:/usr/share/nginx/html nginx
最佳实战。

怎么判断挂载的是卷名而不是本机目录名
  不以/开始就是卷名,以/开始就是主机名。 
 
#改变文件的读写权限
#ro:readonly rw:readwrite; 指定容器对我们这个挂载出来的内容的读写权限
docker run -d -P --name nginx04 -v nginx04conf:/etc/nginx:ro -v nginx04html:/usr/share/nginx/html:rw nginx
ro:效果
root@c721b01b2752:/etc/nginx# echo 123 > nginx.conf
bash: nginx.conf: Read-only file system
容器内不能再对ro指定的所有进行修改了。

我们以使用Docker的方式安装MySQL为例,快速体会Docker的基本操作

镜像操作

下载镜像 docker pull mysql

#我们应该先去Docker Hub寻找我们感兴趣的镜像
docker pull image_name[:Tag]
#1、tag一般为镜像的版本,不指定默认下载latest版本
#2、默认镜像是从Docker Hub下载,国内比较慢,推荐使用自己的阿里云加速
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["https://82m9ar63.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker

l8u4jp1z.png

  • 以上下载过程看出,镜像是分层的(Layer)。c499e6d256d6是当前层的唯一id(完整的id为256bit,64个十六进制字符组成)。
  • 不同的镜像如果有相同的层,本地只会存储一份,减小了存储空间
  • 严格说,下载镜像需要制定指定仓库名称,不过从Docker Hub下载的可以忽略前缀。如

    • docker pull docker.io/library/mysql:5.7

列出镜像 docker images

docker images

l8u4k2c4.png

  • REPOSITORY:来源于哪个仓库
  • TAG:镜像版本标签信息
  • IMAGE ID :镜像唯一id
  • CREATED:镜像最后更新时间
  • SIZE:镜像大小

查看详情 docker inspect

docker inspect image_name[:tag]
docker inspect image_id  

删除镜像 docker rmi

docker rmi image_name[:tag] 或者 docker rmi image_id

理解镜像

1、疑问一:

Docker每一个容器都是一个完整的这个应用的运行环境。所有应用最起码的基本环境是linux

SB微服务做成镜像。基本环境就是java环境,

如果我下载了100个镜像,启动了100个容器。100个linux在运行?

UFS:特点;git。增量记录文件改变。分层系统。需要经常读写变化的,只在变化层。

容器操作

启动容器

#docker run [OPTIONS] IMAGE [COMMAND] [ARG...] 常用选项
-d  守护态运行
-p  Publish a container's port(s) to the host ( container和host端口映射)
-i  以交互模式运行容器,通常与 -t 同时使用
-t  为容器重新分配一个伪输入终端,通常与 -i 同时使用
--name="nginx-lb"  为容器指定一个名称
-v, --volume value  Bind mount a volume (default [])
docker run -d -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 --name hello-mysql mysql:5.7

#查看所有运行中的容器
docker ps 
#查看所有容器
docker ps -a
#docker create 和 docker run的区别
docker create -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 --name hello-mysql mysql:5.7
#create新建容器,run新建并启动。create相当于 run -d设置

进入容器

#docker exec  [OPTIONS] CONTAINER COMMAND [ARG...]
#Run a command in a running container
docker exec -it hello-mysql /bin/bash    
#尝试连接MySQL
mysql -uroot -p123456
#扩展
docker exec -d hello-mysql touch /hello.txt
docker exec -it hello-mysql mysql -uroot -p

#删除
docker rm container_id/container_name
#查看运行日志
docker logs container_id/container_name

其他命令

Docker 命令手册

可视化

  • Portainer(先用这个)
docker run -d -p 8088:9000 \
--restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer
  • Rancher(CI/CD再用这个)
#安装rancher-server
docker run --name rancher-server -p 8000:8080 -v /etc/localtime:/etc/localtime:ro  -d  rancher/server
#安装agent
docker run --rm --privileged -v /var/run/docker.sock:/var/run/docker.sock -v /var/lib/rancher:/var/lib/rancher rancher/agent:v1.2.11 http://39.101.191.131:8000/v1/scripts/D3DBD43F263109BB881F:1577750400000:7M0yBzCw4XSxJklD7TpysYIpI

为什么是Docker?

l8u4gvqk.png

Docker 是一个开源的应用容器引擎,基于 Go 语言 并遵从 Apache2.0 协议开源。

Docker解决了什么问题

  • 快速交付和部署(镜像与容器)
  • 资源的高效利用和隔离(高密度部署)
  • 轻松的迁移和扩展(一次封装,到处运行)

l8u4hhsd.png

Docker使用步骤

  • 安装Docker(安装应用商店)
  • 寻找/下载镜像(寻找/下载app)
  • 启动容器(启动应用)
  • 移植(别的手机安装应用商店,继续以前流程)

容器化对比虚拟机

对比属性ContainerVM
隔离性基于进程隔离提供资源的完全隔离
启动时间秒级分钟级
内核共用宿主机内核使用独立内核
占用资源MB级GB级
系统支持容量单机支持上千个容器一般几十个

核心概念

l8u4irdr.png

Docker 镜像

Docker镜像类似于虚拟机镜像,可以将他理解为一个只读的模板。

Docker 容器

Docker容器类似于一个轻量级的沙箱,Docker利用容器来运行和隔离应用。容器是从镜像创建来的。容器可以启动、停止、删除,容器之间彼此隔离,互不可见。

可以把容器看做是一个简易版的Linux系统环境(包括root用户权限、进程空间、用户空间和网络空间等)以及运行在其中的应用程序打包而成的盒子

Docker 仓库

Docker仓库是存储镜像的仓库。可以有Public(公有仓库)和Private(私有仓库)。最大的公有仓库是Docker Hub

Docker面向对象
镜像
容器对象

安装启动

阿里云安装

yum install docker
systemctl enable docker
systemctl start docker

docker -v
docker info

标准方式安装

#移除旧版本
yum remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-engine
#安装Docker其他依赖
yum install -y yum-utils \
  device-mapper-persistent-data \
  lvm2
#设置Docker yum源
yum-config-manager \
    --add-repo \
    https://download.docker.com/linux/centos/docker-ce.repo
#安装Docker CE
yum install -y docker-ce docker-ce-cli containerd.io

#安装指定版本的Docker
yum list docker-ce --showduplicates | sort -r
yum install docker-ce-<VERSION_STRING> docker-ce-cli-<VERSION_STRING> containerd.io
#启动Docker
systemctl enable docker
systemctl start docker