记录 Docker 的学习过程 (安装基础篇)
docker 通过内核来实现 特点是效率高
1. centos7 三台(推荐2c 4g 最低 1c1g)
2. 关闭防火墙 selinux
3. 做好主机名解析,三台能互相ping通主机名
host参考文件
--------------------------------------------------------------------
192.168.56.11 linux-node1 linux-node1.example.com
192.168.56.12 linux-node2 linux-node2.example.com
192.168.56.13 linux-node3 linux-node3.example.com
---------------------------------------------------------------------
4.时间同步
wget https://download.docker.com/linux/centos/docker-ce.repo -O /etc/yum.repos.d/docker-ce.repo
yum -y install epel-release
yum -y install docker-ce
yum -y install python-pip
pip3 install --upgrade pip
pip3 install docker-compose
systemctl enable docker.service
systemctl start docker.service
修改源否则会非常的慢
mkdir -p /etc/docker
tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://a14c78qe.mirror.aliyuncs.com"]
}
EOF
systemctl daemon-reload
systemctl restart docker
开始pull镜像
docker pull centos
docker pull busybox
docker pull mysql
docker pull nginx
docker pull alpine
docker pull aclstack/mem
docker pull aclstack/cpu
docker pull progrium/consul
docker pull sebp/elk
docker pull fluent/fluentd
修改
/etc/docker/daemon.json 文件为如下所示:
{
"registry-mirrors": ["https://a14c78qe.mirror.aliyuncs.com"], # 设置docker运行时的根目录
"dns": ["192.168.56.2","192.168.56.2"], # 设置docker的dns
"data-root": "/data/docker" #设置docker运行时的根目录
}
-------------------------------------------------------
这里有一个额外的配置,如果你想要使用api调用 销毁容器需要修改下面的配置
vi /usr/lib/systemd/system/docker.service
修改 14行为ExecStart=/usr/bin/dockerd -H tcp://192.168.56.11 -H unix:///var/run/docker.sock
需要执行systemctl daemon-reload systemctl restart docker 是配置生效
验证
[root@linux-node1 ~]# docker -H 192.168.56.11 info #使用这条命令验证刚刚修改的配置是否生效,如果能看到下面的信息就没问题
Client:
Debug Mode: false
Server:
Containers: 0
Running: 0
Paused: 0
Stopped: 0
Images: 9
Server Version: 19.03.6
Storage Driver: overlay2
Backing Filesystem: xfs
Supports d_type: true
Native Overlay Diff: true
Logging Driver: json-file
Cgroup Driver: cgroupfs
Plugins:
Volume: local
Network: bridge host ipvlan macvlan null overlay
Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog
Swarm: inactive
Runtimes: runc
Default Runtime: runc
Init Binary: docker-init
containerd version: b34a5c8af56e510852c35414db4c1f4fa6172339
runc version: 3e425f80a8c931f88e6d94a8c831b9d5aa481657
init version: fec3683
Security Options:
seccomp
Profile: default
Kernel Version: 3.10.0-1062.el7.x86_64
Operating System: CentOS Linux 7 (Core)
OSType: linux
Architecture: x86_64
CPUs: 2
Total Memory: 1.934GiB
Name: linux-node1.example.com
ID: 2RXW:LE2K:YYOT:SR3Q:TY3Y:5P6K:IRCA:3DHD:GTMQ:YOGG:XSBZ:GSSO
Docker Root Dir: /data/docker
Debug Mode: false
Registry: https://index.docker.io/v1/
Labels:
Experimental: false
Insecure Registries:
127.0.0.0/8
Registry Mirrors:
https://a14c78qe.mirror.aliyuncs.com/
Live Restore Enabled: false
WARNING: API is accessible on http://192.168.56.11:2375 without encryption.
Access to the remote API is equivalent to root access on the host. Refer
to the 'Docker daemon attack surface' section in the documentation for
more information: https://docs.docker.com/engine/security/security/#docker-daemon-attack-surface
WARNING: bridge-nf-call-iptables is disabled
WARNING: bridge-nf-call-ip6tables is disabled
至此,额外配置结束
-------------------------------------------------------
# netstat -tnlp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 1075/master
tcp 0 0 192.168.56.11:2375 0.0.0.0:* LISTEN 2286/dockerd
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 843/sshd
tcp6 0 0 ::1:25 :::* LISTEN 1075/master
tcp6 0 0 :::22 :::* LISTEN 843/sshd
docker的默认端口是2375
查找镜像
[root@linux-node1 ~]# docker search lnmp
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
2233466866/lnmp https://hub.docker.com/r/2233466866/lnmp 39
winstonpro/lnmp based on ubuntu 14.04 25
twang2218/lnmp-nginx 这是 LNMP 示例中的 nginx 镜像 22 [OK]
duckll/lnmp webservice 15 [OK]
dzer/lnmp lnmp环境 11
fbraz3/lnmp An easy-to-use LNMP/LEMP image, with Ubuntu … 8
......
镜像有2种,一种官方镜像,一种第三方镜像。区别在于第三方镜像的命名方式为 用户名/镜像名称 官方镜像只有文件名
查看本地镜像
# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest 2073e0bcb60e 2 weeks ago 127MB
mysql latest 791b6e40940c 2 weeks ago 465MB
alpine latest e7d92cdc71fe 4 weeks ago 5.59MB
centos latest 470671670cac 4 weeks ago 237MB
验证docker是否正常工作使用下面的命令
# docker run hello-world
如果可以看到下面的内容证明docker运行ok
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
1b930d010525: Pull complete
Digest: sha256:9572f7cdcee8591948c2963463447a53466950b3fc15a247fcad1917ca215a2f
Status: Downloaded newer image for hello-world:latest
Hello from Docker!
This message shows that your installation appears to be working correctly.
To generate this message, Docker took the following steps:
1. The Docker client contacted the Docker daemon.
2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
(amd64)
3. The Docker daemon created a new container from that image which runs the
executable that produces the output you are currently reading.
4. The Docker daemon streamed that output to the Docker client, which sent it
to your terminal.
To try something more ambitious, you can run an Ubuntu container with:
$ docker run -it ubuntu bash
Share images, automate workflows, and more with a free Docker ID:
https://hub.docker.com/
For more examples and ideas, visit:
https://docs.docker.com/get-started/
docker的常用命令
docker的run相当于 create+start
下面run一个镜像
# docker run -it --name my_centos centos bash # -i表示开启交互模式 -t表示开启一个tty终端 如果不加bash,那么会执行镜像作者设置的开机自动执行程序,bash相当于覆盖镜像的开机自动执行程序。也可以将bash替换为想要设置的开机自动执行程序
执行后发现命令行变成了
[root@72fb0696b036 /]#
此时我们就进到了刚刚创建的容器中
[root@72fb0696b036 /]# exit #exit 关闭容器,exit执行后相当于销毁了当前进程,如果一个容器中一条进程都没有,那么会触发docker的默认机制,即关闭容器
[root@linux-node1 ~]# docker ps #查看正在运行的容器
CONTAINER ID IMAGE COMMAND CREATED STATUS POTS NAMES
此时没有看到正在运行的容器,所以就印证了exit是关闭容器了,我们再重启启动容器,
启动容器有2中方法,一种是使用容器名称启动,另外一种是使用id启动
# docker start my_centos
my_centos
# docker ps #查看在线容器
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
72fb0696b036 centos "bash" 12 minutes ago Up 30 seconds my_centos
下面我们可以连接容器了,使用
# docker attach my_centos
[root@72fb0696b036 /]#
这种连接方式会带来一个问题就是,如果其他用户从别的终端连过来,就可以互相看到对方的操作了,所以不推荐用这种方式连接,那现在我们怎么做才能退出这个容器呢,因为刚刚的exit直接关闭容器了,此时需要按住ctrl键,先按p,再按q就可以退出了
再来看另外以各种连接方式
# docker exec -it my_centos bash #这条命令相当于 使用my_centos执行bash命令
[root@72fb0696b036 /]# ps -ef
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 16:35 pts/0 00:00:00 bash
root 15 0 0 16:59 pts/1 00:00:00 bash
此时我们发现刚刚的这种连接方式就是又开启了一个新的tty会话,而之前的attach的方式则是直接连接到会话上.
此时如果我们执行exit命令,这个容器会被关闭,答案是不会,因为通过ps -ef我们可以看到 当前有2个bash,如果仅仅销毁一个bash,只要还剩余1个bash,那么容器就不会被关闭,只有当一个进程都没有的时候,容器才会出发docker的默认机制,导致容器被关闭
我们再执行几条命令试试看
# docker exec my_centos mkdir /root/newfolder
# docker exec my_centos ls /root
\anaconda-ks.cfg
anaconda-post.log
newfolder
original-ks.cfg
可以发现如果执行的命令感觉就在后台执行了,也可以使用ls这种有回显的命令,直接看到结果,而不需要进入容器中。
这里需要主机的是有些镜像不带bash,这时要通过sh的方式进入,如:
# docker run -it --name mini_os alpine bash
docker: Error response from daemon: OCI runtime create failed: container_linux.go:346: starting container process caused "exec: \"bash\": executable file not found in $PATH": unknown.
ERRO[0001] error waiting for container: context canceled
通过bash就会报错,所以要通过sh 的方式进入,
# docker run -it --name mini_os alpine sh
docker: Error response from daemon: Conflict. The container name "/mini_os" is already in use by container "9c2543343a1f6dab313d42f23f4d72e979357108ab23b0d9081aa68bf0ba33fc". You have to remove (or rename) that container to be able to reuse that name.
See 'docker run --help'.
但是这里又报错了,因为min_os这个名称已经被占用了,所以下面我们要开始删除容器
# docker ps -a #显示所有容器
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6886ab431238 alpine "bash" 15 hours ago Created mini_os
72fb0696b036 centos "bash" 16 hours ago Exited (0) 15 hours ago my_centos
# docker rm -f 6886ab431238 #删除一个
6886ab431238
# docker rm -f 72fb0696b036 976816b7b3b5 #删除多个
72fb0696b036
976816b7b3b5
此时就可以创建刚才的容器了
# docker run -it --name mini_os alpine sh
/ #
下面开始手动制作镜像
先试着创建一个centos8的容器
# docker run -it --name my_nginx centos bash
[root@e4ba0d86ba9d /]# yum -y install nginx
centos8 nginx直接就安装上了
下面试试看centos7
# docker pull centos:7 #拉取centos7镜像
# docker run -it --name my_centos7 centos:7 bash
用yum安装貌似不行,所以我们要下载安装epel
[root@7356bb3d39e9 /]# rpm -ivh https://mirrors.aliyun.com/epel/epel-release-latest-7.noarch.rpm
此时就可以通过yum安装nginx了
[root@7356bb3d39e9 /]# yum -y install nginx php-fpm supervisor #安装 nginx php supervisor(多进程管理工具)
我们来看下supervisor的配置文件
/etc/supervisord.conf
重要的是最后一行,配置文件的位置,以及后缀为ini
files = supervisord.d/*.ini
创建一个配置文件
[root@7356bb3d39e9 /]# vi /etc/supervisord.d/php_nginx.ini
贴入下面配置文件
[supervisord]
nodaemon=true
[program:nginx]
command=/usr/sbin/nginx -g "daemon off;" #前台方式启动
[program:phpfpm]
command=/usr/sbin/php-fpm -F -c /etc/php.ini #前台方式启动
autostart = true
startsecs = 3
autorestart = true
startretries = 3
user = root
redirect_stderr = false
stdout_logfile_maxbytes = 50MB
stdout_logfile_backups = 20
下面来启动它
[root@7356bb3d39e9 supervisord.d]# supervisord
因为是前台运行所以此时我们什么都做不了
我们新建一个tty会话
# docker exec -it my_centos7 bash
[root@b6fee5812500 /]# ps -ef
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 08:47 pts/0 00:00:00 bash
root 298 1 0 10:27 pts/0 00:00:00 /usr/bin/python /usr/bin/superv
root 301 298 0 10:27 pts/0 00:00:00 nginx: master process /usr/sbin
root 302 298 0 10:27 pts/0 00:00:00 php-fpm: master process (/etc/p
nginx 303 301 0 10:27 pts/0 00:00:00 nginx: worker process
nginx 304 301 0 10:27 pts/0 00:00:00 nginx: worker process
apache 305 302 0 10:27 pts/0 00:00:00 php-fpm: pool www
apache 306 302 0 10:27 pts/0 00:00:00 php-fpm: pool www
apache 307 302 0 10:27 pts/0 00:00:00 php-fpm: pool www
apache 308 302 0 10:27 pts/0 00:00:00 php-fpm: pool www
apache 309 302 0 10:27 pts/0 00:00:00 php-fpm: pool www
root 310 0 0 10:29 pts/1 00:00:00 bash
root 323 310 0 10:29 pts/1 00:00:00 ps -ef
可以看到supervisor的进程已经运行了
[root@b6fee5812500 /]# netstat -tnlp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 127.0.0.1:9000 0.0.0.0:* LISTEN 302/php-fpm: master
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 301/nginx: master p
tcp6 0 0 :::80 :::* LISTEN 301/nginx: master p
可以看到 9000 和 80 端口都已经起来了
[root@b6fee5812500 /]# exit #退出
下面我们打包刚才的镜像
# docker commit -m "nginx and php" my_centos7 newimages2020:v1 # -注释
sha256:21f0da5d69085d6bded6e6ce66506a1b86bbfea147ceb6960d5c195b39938e5e
# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
newimages2020 v1 c8029ab89369 19 seconds ago 467MB
此时可以看到刚刚打包的镜像了,刚刚我们是基于自己的容器创建镜像,下面我们用刚刚创建的镜像再制作一个容器
# docker run -it -p 80:80 --name nginx_v1 c8029ab89369 supervisord #-p 指定端口映射 将本机80映射到容器的80 nginx-v1是我们起的名字,后面跟上刚刚创建的镜像的id,再跟上要执行的命令
# docker ps #可以看到映射关系
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
dd8cc96a8b38 c8029ab89369 "supervisord" 8 minutes ago Up 8 minutes 0.0.0.0:80->80/tcp nginx_v1
b6fee5812500 centos:7 "bash" 19 minutes ago Up 19 minutes my_centos7
此时打开浏览器 192.168.56.11 发现映射已经成功了,我们再来看php的部分
# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
dd8cc96a8b38 c8029ab89369 "supervisord" 41 minutes ago Up 41 minutes 0.0.0.0:80->80/tcp nginx_v1
b6fee5812500 centos:7 "bash" 51 minutes ago Up 51 minutes my_centos7
连接到刚刚创建的容器中
# docker exec -it nginx_v1 bash
[root@dd8cc96a8b38 /]# vi /usr/share/nginx/html/phpinfo.php 在nginx默认web目录中创建phpinfo文件
贴入以下内容
<?php
phpinfo();
?>
然后再修改nginx的配置文件
[root@dd8cc96a8b38 /]# vi /etc/nginx/nginx.conf
在56行增加以下内容
location ~ \.php?.*$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
[root@dd8cc96a8b38 /]# nginx -t #检查配置是否ok
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@dd8cc96a8b38 /]# nginx -s reload #重启nginx
[root@dd8cc96a8b38 /]# supervisorctl status
nginx RUNNING pid 8, uptime 1:02:24
phpfpm RUNNING pid 9, uptime 1:02:24
[root@dd8cc96a8b38 /]# supervisorctl reload #也可以通过重启 supervisor来实现
[root@dd8cc96a8b38 /]# supervisorctl status
nginx RUNNING pid 52, uptime 0:00:04
phpfpm RUNNING pid 53, uptime 0:00:04
此时,尝试打开http://192.168.56.11/phpinfo.php 发现可以打开页面了
下面开始制作mysql的镜像,mysql比较特殊
# docker pull mysql:5.7 #先pull一个5.7 8的坑太多
# docker run -it --name mysql -p 8888:3306 mysql:5.7
2020-02-20 17:13:10+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 5.7.29-1debian9 started.
2020-02-20 17:13:10+00:00 [Note] [Entrypoint]: Switching to dedicated user 'mysql'
2020-02-20 17:13:10+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 5.7.29-1debian9 started.
2020-02-20 17:13:10+00:00 [ERROR] [Entrypoint]: Database is uninitialized and password option is not specified
You need to specify one of MYSQL_ROOT_PASSWORD, MYSQL_ALLOW_EMPTY_PASSWORD and MYSQL_RANDOM_ROOT_PASSWORD
直接创建会报错
# docker run -it --name mysql -p 8888:3306 -e MYSQL_ALLOW_EMPTY_PASSWORD=true mysql5.7 #使用-e参数设置变量后执行就可以了
此时新打开一个会话,先安装mysql客户端
yum -y install mysql
然后尝试连接
# mysql -uroot -h 127.0.0.1 -P 8888
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.29 MySQL Community Server (GPL)
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
发现可以正常连接了
# docker run -it --name mysql2 -p 8888:3306 --rm mysql #-rm参数在初学时很实用,生产时勿用!如果参数输入错误导致容器起不来,正常情况下需要删除容器再重建,加上-rm则会自动删除停止(未启动)的容器
docker run -it --name mysql2 -p 8888:3306 -e MYSQL_RANDOM_ROOT_PASSWORD=true mysql:5.7
创建mysql容器并设置一个随机密码,会在屏幕上输出一组随机密码如下
2020-02-21 08:12:48+00:00 [Note] [Entrypoint]: GENERATED ROOT PASSWORD: xei4ohD2oojahb3eejoh2eegoh2eith1
使用随机密码登录
# mysql -uroot -h 127.0.0.1 -P 8888 -pxei4ohD2oojahb3eejoh2eegoh2eith1
mysql不要使用root用户运行,否则会有很大的安全隐患
# docker login #注册docker账户,上传镜像
Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
下面看容器的资源限制
cpu 内存都可以做限制,io不推荐 (效果不好)
先看内存,这个镜像的作用是每秒请求10MB内存
# docker run -it -m 50M aclstack/mem mem
allocate 10MB memory.
allocate 10MB memory.
allocate 10MB memory.
allocate 10MB memory.
allocate 10MB memory.
allocate 10MB memory.
allocate 10MB memory.
allocate 10MB memory.
allocate 10MB memory.
allocate 10MB memory.
# tail -f /var/log/messages
Feb 21 16:49:01 linux-node1 kernel: Memory cgroup out of memory: Kill process 4870 (mem) score 982 or sacrifice child
可以发现内存被耗尽了,但是很奇怪的是为什么消耗了100M(消耗了swap)
CPU的限制是按照百分比限制的,假如有2台机器 A和B 假如 A的权重为2048 B的为1024 那么如果A机器不紧张的时,B完全可以跑满cpu
下面这个镜像时用来跑满CPU的
# docker run --cpuset-cpus 0 -c 2048 aclstack/cpu cpu #--cpuset-cpus 0表示使用cpu0 -c 2048 设置优先级为2048(越高越大)
此时再打开一个会话查看top 按下1 可以发现cpu0被占满了
top - 17:08:12 up 1:19, 3 users, load average: 1.23, 0.85, 0.42
Tasks: 109 total, 2 running, 107 sleeping, 0 stopped, 0 zombie
%Cpu0 : 99.6 us, 0.4 sy, 0.0 ni, 0.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu1 : 0.0 us, 0.0 sy, 0.0 ni, 99.7 id, 0.0 wa, 0.0 hi, 0.3 si, 0.0 st
KiB Mem : 2027968 total, 1144192 free, 311544 used, 572232 buff/cache
KiB Swap: 4194300 total, 4193808 free, 492 used. 1557292 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
4989 root 20 0 4056 524 300 R 100.0 0.0 5:48.67 cpu
此时再打开一个会话
# docker run --cpuset-cpus 0 -c 1024 aclstack/cpu cpu #使用1024权重,1024位默认值
top - 17:10:49 up 1:22, 4 users, load average: 1.54, 1.06, 0.56
Tasks: 114 total, 3 running, 111 sleeping, 0 stopped, 0 zombie
%Cpu0 : 99.5 us, 0.5 sy, 0.0 ni, 0.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu1 : 0.0 us, 0.3 sy, 0.0 ni, 96.8 id, 0.0 wa, 0.0 hi, 2.9 si, 0.0 st
KiB Mem : 2027968 total, 1096928 free, 358144 used, 572896 buff/cache
KiB Swap: 4194300 total, 4193808 free, 492 used. 1510364 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
4989 root 20 0 4056 524 300 R 66.4 0.0 8:17.78 cpu 第一台
5088 root 20 0 4056 520 300 R 33.2 0.0 0:06.98 cpu 第二台
可以发现第一台和第二台的cpu占比是根据权重分配的,如果第一台不忙时,第二台可以跑满cpu,当第一台繁忙时,会按照权重划分资源
记录 Docker 的学习过程 (安装基础篇)的更多相关文章
- 记录 Docker 的学习过程 (日志篇)
日志收集 elk 在node3上操作 docker pull sebp/elk:5610 node3# sysctl vm.max_map_count=262144 node3# docker run ...
- 记录 Docker 的学习过程 (网络篇之跨主机互通)
下面从node3上操作node3# docker run -d -p 8500:8500 --name consul progrium/consul -server -bootstrap node3# ...
- 记录 Docker 的学习过程 (网络篇)
打开2个会话,分别运行以下命令 # docker run -it -P --name nginx2 nginx #-P 端口随机映射 再打开一个会话查看 运行中的容器 # docker ps -aCO ...
- Docker虚拟化实战学习——基础篇(转)
Docker虚拟化实战学习——基础篇 2018年05月26日 02:17:24 北纬34度停留 阅读数:773更多 个人分类: Docker Docker虚拟化实战和企业案例演练 深入剖析虚拟化技 ...
- 新一代Java程序员必学的Docker容器化技术基础篇
Docker概述 **本人博客网站 **IT小神 www.itxiaoshen.com Docker文档官网 Docker是一个用于开发.发布和运行应用程序的开放平台.Docker使您能够将应用程序与 ...
- docker进阶之路-基础篇 | 一:环境搭建
转载请注明作者及出处: 作者:银河架构师 原文链接:https://www.cnblogs.com/luas/p/12061747.html 一.准备工作 查看内核 Docker 要求 CentOS ...
- docker进阶之路-基础篇 | 二:portainer安装与基本使用
转载请注明作者及出处: 作者:银河架构师 原文链接:https://www.cnblogs.com/luas/p/12061755.html 简介 Portainer 是轻量级,跨平台,开源的管理D ...
- Linux虚拟网络:Docker网络知识之基础篇
我们在工作中应用了docker容器化技术,服务的部署.维护和扩展都方便了很多.然而,近期在私有化部署过程中,由于不同服务器环境的复杂多变,常常遇到网络方面的问题,现象为容器服务运行正常,但宿主机.容器 ...
- 记录 Docker 的学习过程 (dockerfile自动制作镜像)
自动制作镜像 通过编写dockerfile来自动创建镜像 #vi Dockerfile #编辑dockerfile文件,一定要以这个名字命名 #cat Dockerfile #导入哪个基础镜像FROM ...
随机推荐
- 网易MuMu模拟器不显示Menu(菜单)键的解决办法
解决方法一: 前提:需要一个键盘 步骤: 1.直接按下键盘上的Menu键. 解决方法二: 前提:需要Root之后的文件浏览器 步骤: 1.在文件管理器中打开 /System 文件夹: 2.复制 bui ...
- Android中使用getDrawable时提示:Call requires API level 21(current min is 15)
场景 在通过getDrawable方法获取照片资源时提示: Call requires API level 21(current min is 15) 注: 博客: https://blog.csdn ...
- Linux kernel简介
内核体系设计分:单内核,微内核 windows是微内核设计. Linux是单内核设计,但充分借鉴了为微内核体系的优点,为内核引入了模块化机制. 内核的组成部分 kernel:内核核心,一般为bz压缩的 ...
- asp.net abp模块化开发之通用树2:设计思路及源码解析
一.前言 上一篇大概说了下abp通用树形模块如何使用,本篇主要分析下设计思路. 日常开发中会用到很多树状结构的数据,比如:产品的多级分类.省市区县,大多数系统也会用到类似“通用字典/数据字典”的功能, ...
- SQL JOIN 的解析
1.SQL语句结构 select distinct < select_list > from < left_table > < join_type > joi ...
- opencv —— morphologyEx 开运算、闭运算、形态学梯度、顶帽、黑帽
开运算:先腐蚀后膨胀. 能够排除小亮点. 闭运算:先膨胀后腐蚀. 能够排除小黑点. 形态学梯度:膨胀图 — 腐蚀图. 对二值图像进行这一操作,可将图块的边缘突出出来,故可用来保留物体边缘轮廓. 顶帽: ...
- 后台实战——用户登录之JWT
https://blog.csdn.net/jackcheng_ht/article/details/52670211
- Vue图片验证码-自定义组件高级版
最近项目中要用到图片验证码,网上一查有很多,基本都是千篇一律的4位纯数字验证码.首先得感谢那位一代目兄台提供的模板,由于不能满足需求,所以对其进行了改造升级. 经改造的图片验证码能满足一下情形使用:① ...
- LeetCode30 Hard 查找所有子串
本文始发于个人公众号:TechFlow,原创不易,求个关注 链接 Substring with Concatenation of All Words 难度 Hard 描述 给定一个字符串s作为母串,和 ...
- 轻量级RPC设计与实现第四版
在本版本中引入了SPI机制,关于Java的SPI机制与Dubbo的SPI机制在以前的文章中介绍过. 传送门:Dubbo的SPI机制与JDK机制的不同及原理分析 因为设计的RPC框架是基于Spring的 ...