ShawnYoung's Blog

love&&curiosity

CommonJS

ESM

Kubernetes镜像

简介

Kubernetes是一个开源系统,用于容器化应用的自动部署、扩缩和管理。它将构成应用的容器按逻辑单位进行分组以便于管理和发现。

下载地址:https://mirrors.aliyun.com/kubernetes/

配置方法

Debian / Ubuntu

1
2
3
4
5
6
7
apt-get update && apt-get install -y apt-transport-https
curl https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | apt-key add -
cat <<EOF >/etc/apt/sources.list.d/kubernetes.list
deb https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main
EOF
apt-get update
apt-get install -y kubelet kubeadm kubectl

CentOS / RHEL / Fedora

1
2
3
4
5
6
7
8
9
10
11
12
cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF
setenforce 0
yum install -y kubelet kubeadm kubectl
systemctl enable kubelet && systemctl start kubelet

ps: 由于官网未开放同步方式, 可能会有索引gpg检查失败的情况, 这时请用 yum install -y --nogpgcheck kubelet kubeadm kubectl 安装

相关链接

在Java8及高版本以上的版本在调用ssl时会出现javax.net.ssl.SSLHandshakeException: No appropriate protocol的异常。

1
2
3
4
5
6
7
8
9
10
javax.net.ssl.SSLHandshakeException: No appropriate protocol (protocol is disabled or cipher suites are inappropriate)
at sun.security.ssl.HandshakeContext.<init>(HandshakeContext.java:171) ~[na:1.8.0_292]
at sun.security.ssl.ClientHandshakeContext.<init>(ClientHandshakeContext.java:98) ~[na:1.8.0_292]
at sun.security.ssl.TransportContext.kickstart(TransportContext.java:220) ~[na:1.8.0_292]
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:428) ~[na:1.8.0_292]
at com.mysql.cj.protocol.ExportControlled.performTlsHandshake(ExportControlled.java:316) ~[mysql-connector-java-8.0.17.jar:8.0.17]
at com.mysql.cj.protocol.StandardSocketFactory.performTlsHandshake(StandardSocketFactory.java:188) ~[mysql-connector-java-8.0.17.jar:8.0.17]
at com.mysql.cj.protocol.a.NativeSocketConnection.performTlsHandshake(NativeSocketConnection.java:99) ~[mysql-connector-java-8.0.17.jar:8.0.17]
at com.mysql.cj.protocol.a.NativeProtocol.negotiateSSLConnection(NativeProtocol.java:331) ~[mysql-connector-java-8.0.17.jar:8.0.17]
... 68 common frames omitted

解决办法如下:

  1. 修改jre/lib/security/java.security中的disabledAlgorithms,删除SSLv3, TLSv1, TLSv1.1,然后重启应用即可。在vim下,可以使用/disabledAlgorithms快速查找。

jdk.tls.disabledAlgorithms=RC4, DES, MD5withRSA, \ DH keySize < 1024, EC keySize < 224, 3DES_EDE_CBC, anon, NULL, \ include jdk.disabled.namedCurves

如果修改了,保存了,重启了还是没有效果,就看下面这个方法:

  1. 修改jdk配置文件/etc/crypto-policies/back-ends/java.config,类似上面方法一样,删除SSLv3, TLSv1, TLSv1.1,保存重启应用。

jdk.tls.disabledAlgorithms=DH keySize < 2048, SSLv2, SSLv3, TLSv1.1, DHE_DSS, RSA_EXPORT, DHE_DSS_EXPORT, DHE_RSA_EXPORT, DH_DSS_EXPORT, DH_RSA_EXPORT, DH_anon, ECDH_anon, DH_RSA, DH_DSS, ECDH, 3DES_EDE_CBC, DES_CBC, RC4_40, RC4_128, DES40_CBC, RC2, HmacMD5

  1. 另外jdk奇数版本可用,偶数版本有上面这个问题,可用通过yum --showduplicate list java* | grep 1.8.0查看可用的版本,选择奇数版本安装也能解决这个问题。

  2. 更新crypto-policies

    update-crypto-policies --set LEGACY

1
2
3
4
5
6
7
8
9
 docker run -d -p 3306:3306 \
--privileged=true \
-v /opt/mysql/conf:/etc/mysql/conf.d \
-v /opt/mysql/data:/var/lib/mysql \
-v /opt/mysql/log:/var/log/mysql \
-e MYSQL_ROOT_PASSWORD=123456 \
--name mysql01 mysql:5.7 \
--character-set-server=utf8mb4 \
--collation-server=utf8mb4_unicode_ci

docker安装oracle

1、安装docker环境。

2、开始拉取oracle镜像

1
docker pull registry.cn-hangzhou.aliyuncs.com/helowin/oracle_11g

3、下载完成后,查看镜像

1
docker images

4、创建容器

1
docker run -d -p 1521:1521 --name oracle11g registry.cn-hangzhou.aliyuncs.com/helowin/oracle_11g

可以写成shell脚本,下次打开oracle数据库就可以一条命令创建容器。

shell脚本如下:

1
2
3
4
5
6
7
8
9
# BEGIN ANSIBLE MANAGED BLOCK
#!/bin/bash
docker rm -f oracle11;
docker run -it -d -p 1521:1521
--privileged=true \
-v /opt/oracle/oradata/dbs:/home/oracle/app/oracle/product/11.2.0/dbhome_2/dbs \
-v /opt/oracle/oradata:/home/oracle/app/oracle/oradata \
-e ORACLE_PWD=helowin --name oracle11 registry.cn-hangzhou.aliyuncs.com/helowin/oracle_11g
# END ANSIBLE MANAGED BLOCK

但为了保存上一次容易的配置值,是不建议写这个shell脚本的,下次打开直接用docker start oracle11命令打开。

如果创建成功能会返回容器id

5、进入镜像进行配置

1
docker exec -it oracle11 bash

6、进行sql登录

1
sqlplus /nolog

发现没有该命令,需要先配置环境变量,所以切换root用户。

1
su root 

输入密码:helowin

7、编辑profile文件配置ORACLE环境变量

打开:vi /etc/profile ,在文件最后写上下面内容:

1
2
3
export ORACLE_HOME=/home/oracle/app/oracle/product/11.2.0/dbhome_2
export ORACLE_SID=helowin
export PATH=$ORACLE_HOME/bin:$PATH

8、保存后执行source /etc/profile 加载环境变量;

9、创建软连接

1
ln -s $ORACLE_HOME/bin/sqlplus /usr/bin

10、切换到oracle 用户

1
su - oracle

这里还要说一下,一定要写中间的短横线 - 必须要,否则软连接无效

11、登录sqlplus并修改sys、system用户密码

1
2
3
4
5
6
7
8
sqlplus /nolog   --登录
conn /as sysdba --
alter user system identified by system;--修改system用户账号密码;
alter user sys identified by system;--修改sys用户账号密码;
create user test identified by test; -- 创建内部管理员账号密码;
grant connect,resource,dba to yan_test; --将dba权限授权给内部管理员账号和密码;
ALTER PROFILE DEFAULT LIMIT PASSWORD_LIFE_TIME UNLIMITED; --修改密码规则策略为密码永不过期;(会出现坑,后面讲解)
alter system set processes=1000 scope=spfile; --修改数据库最大连接数据;

12、修改以上信息后,需要重新启动数据库;

1
2
3
4
conn /as sysdba
shutdown immediate; --关闭数据库
startup; --启动数据库
exit:退出软链接

*上面提到的其中一个坑说明:*

当执行修改密码的时候出现 : database not open

提示数据库没有打开,不急按如下操作

输入:

1
alter database open;

注意了:这里也许还会提示 : ORA-01507: database not mounted

解决办法:

输入:

1
alter database mount;

输入 :alter database open;

然后就可执行 修改数据库密码的命令了

改完之后输入:

1
ALTER PROFILE DEFAULT LIMIT PASSWORD_LIFE_TIME UNLIMITED;

刷新下表 exit 是退出sql 软连接

13、复制oracle的数据及配置

1
sudo docker cp id:/home/oracle/app/oracle /opt/oracle

  1. DDL (Data Definition Language): 数据定义语言
  2. DML (Data Manipulation Language):数据操作语言
  3. DCL (Data Control Language): 数据控制语言
  4. DQL (Data Query Language): 数据查询语言
  • ddl:数据库或表的结构操作(****)
  • dml:对表的记录进行更新(增、删、改)(****)
  • dql:对表的记录的查询(****,难点)
  • dcl:对用户的创建及授权(****)

DDL

一、数据库

  • 查看所有数据库:

    1
    SHOW DATABASES
  • 切换数据库:

    1
    USE DATABASENAME
  • 创建数据库:

    1
    CREATE DATABASE IF NOT EXISTS MYDB CHARSET=utf8
  • 修改数据库:

    1
    AlTER DATABASE MYDB CHARSET SET utf8 
  • 删除数据库

    1
    drop database MYDB

数据类型

  • int:整型;
  • double :浮点型,例如double(5,2)表示最多5位,其中必须有2位小数,即最大值为999.99;
  • decimal:浮点型 ,在表单钱方面使用该类型,因为不会出现精度缺失问题;
  • char:固定长度字符串类型,char(255);
  • varchar: 可变字符串类型:varchar(65535);
  • text(clob):字符串类型;
  1. tinytext 2^8-1 Byte
  2. text 2^16-1 Byte
  3. mediumtext 2^24-1 Byte
  4. longtext 2^34-1 Byte
  • blob :字节类型;
  1. tinyblob 2^8-1 Byte
  2. blob 2^16-1 Byte
  3. mediumblob 2^24-1 Byte
  4. longblob 2^34-1 Byte
  • date:日期类型,格式为:yyyy-MM-dd;
  • time: 时间类型 格式为:hh:mm:ss
  • timestamp: 时间戳类型;

二、表

  • 创建表:
    1
    CREATE TABLE [IF NOT EXISTS] TABLENAME (cloumn01 type01,cloumn02 type02,cloumn03 type03);
  • 查看当前数据库中所有表名称:SHOW TABLES;
  • 查看指定表的创建语句:SHOW CREATE TABLE 表名(了解);
  • 查看表结构:DESC 表名;
  • 删除表结构:DROP TABLE 表名;
  • 修改表:前缀:ALTER TABLE 表名;
  1. 修改之添加列:
    AlTER TABLE 表名 ADD (
    列名 列类型,
    列名 列类型,

  2. 修改列类型(如果被修改的列已存在数据,那么新的列类型可能会影响到已存在数据):ALTER TABLE 表名 MODIFY 列名 列类型
  3. 修改列名:ALTER TABLE 表名 CHANGE 原列名 新列名 新类型
  4. 删除列:ALTER TABLE 表名 DROP 列名
  5. 修改表名称:ALTER TABLE 原表名 RENAME TO 新表名

DML

  • 添加表记录
    1
    INSERT INTO tableName (c1,c2,c3)values(v1,v2,v3);
  • 修改表记录
    1
    2
    3
    update tableName set c1 = v1,c2 = v2;
    update tableName set c1 = v1,c2 = v2 where c3 = v3 or c4 = v4;
    delete * from stu where gender is null;

DCL

  • 一个项目创建一个用户!一个项目对应的数据库只有一个!
  • 这个用户只能对这个数据库有权限,其他数据库不能操作
  1. 创建用户
  • 在指定的IP地址上登录
1
CREATE USER username@IP IDENTIFIED BY 'password'
  • 在任意的IP地址上登录
1
CREATE USER username@'%' IDENTIFIED BY 'password'
  1. 给用户授权
    1
    2
    3
    4
    -- 部分权限授权
    GRANT CREATE,ALTER,DROP,INSERT,UPDATE,DELETE,SELECT ON mydb.* TO shawn@IP
    -- 所有权限授权
    GRANT ALL ON mydb.* TO username@IP
  2. 撤销授权
    1
    REVOKE CREATE,ALTER,DROP,UPDATE,DELETE ON mydb.* FROM username@IP
  3. 查看权限
    1
    SHOW GRANTS FOR username@IP
  4. 删除用户
    1
    DROP USER username@IP

DQL

1
SELECT * FROM tableName;

常用函数

1
2
3
4
5
6
7
8
9
IFNUll(c1,v1);
DATE_FORMAT("yyyy-MM-dd",'%Y-%m-%d');
CONCAT(v1,v2,v3);
distinct;
-- '_'匹配一个字符
-- '%'匹配零个到N个字符
like '_%';
-- (当前页-1)* 每页记录数
limit (17-1)*8,8

聚合函数

联合查询

聚合函数

2.1. Empty Stream
We should use the empty() method in case of the creation of an empty stream:

Stream streamEmpty = Stream.empty();
We often use the empty() method upon creation to avoid returning null for streams with no element:

public Stream streamOf(List list) {
return list == null || list.isEmpty() ? Stream.empty() : list.stream();
}

阅读全文 »

常用快捷键1

常用快捷键2

  • ctrl + alt + o 代码优化(自动删除多余的包与变量)
  • Alt + F12 打开terminal(终端)
  • ctrl+shift+(+/-) 展开全部折叠全部
  • ctrl+(+/-) 展开折叠当前方法
  • shift + f6 重命名(重构)
  • ctrl + alt + l 代码格式化
  • alt + insert 创建内容
  • psvm main方法
  • sout 输出语句
  • Ctrl + d 复制一行
  • Ctrl + y 删除一行
  • Ctrl + Shift + Up/Down 代码向上/下移动
  • Ctrl + n 搜索类
  • alt + insert 生成代码
  • alt + Enter 导包,生成变量
  • Ctrl + / 或 Ctrl + Shift+ / 单行注释或多行注释
  • fori 回车即可 for循环
  • ctrl + alt + t 代码包围try-catch,if,while等
  • ctrl + alt + -> 向后 ctrl + alt + <- 向前
  • 显示代码结构:alt + 7
  • 显示导航栏:alt + 1
  • 撤销 ctrl + Z
  • REDO 操作 ctrl + shif + z
  • Tab 缩进 shift+Tab 撤销缩进
  • Ctrl + u 选择行
  • alt + f8 查看变量值
  • ctrl + alt +B 查找接口实现类
  • ctrl + h 查看类或接口的继承关系
  • ctrl + o 覆写方法

替换

  • ctrl + r 替换
  • ctrl + shift + r 路径中替换

调试debug

  • F9 调试

Docker容器数据卷

原理:将容器目录挂载到Linux的目录

容器的持久化和同步操作 !容器间也是可以数据共享的

使用数据卷

方式一:直接使用命令来挂载 -v

1
docker run -it -v 主机目录:容器内目录
安装MySQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
# 获取镜像 
[root@localhost ~]# docker pull mysql:5.7

# 不挂载数据
## 查看主机是否有msql服务
[root@localhost home]# ps -ef |grep mysql
root 13049 12627 0 14:40 pts/5 00:00:00 grep --color=auto mysql
## 启动mysql容器
[root@localhost home]# docker run -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7
95a10c860fd5ab401b7d29f728addff9b99f1f2a6b28286d78d9d78958843a6b
## 查看msql容器是否运行
[root@localhost home]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
95a10c860fd5 mysql:5.7 "docker-entrypoint.s…" 6 seconds ago Up 5 seconds 0.0.0.0:3306->3306/tcp, :::3306->3306/tcp, 33060/tcp kind_shannon
## 进入mysql容器内
[root@localhost home]# docker exec -it 95a10c860fd5 /bin/bash
## 登录mysql
root@95a10c860fd5:/# mysql -u root -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.36 MySQL Community Server (GPL)

Copyright (c) 2000, 2021, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
## 查看数据库有哪些
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
4 rows in set (0.00 sec)
## 创建数据库
mysql> create database db01;
Query OK, 1 row affected (0.00 sec)
## 使用数据库
mysql> use db01
Database changed
## 创建表student
mysql> create table student(id int,name varchar(20));
Query OK, 0 rows affected (0.01 sec)
## 向student表插入数据
mysql> insert into student values(1,'z3');
Query OK, 1 row affected (0.04 sec)
## 查询student表所有数据
mysql> select * from student ;
+------+------+
| id | name |
+------+------+
| 1 | z3 |
+------+------+
1 row in set (0.00 sec)

mysql> select * from student;
+------+------+
| id | name |
+------+------+
| 1 | z3 |
| 2 | lisi |
+------+------+
2 rows in set (0.00 sec)
## 查看数据库默认字符集为latin1
mysql> show variables like 'character%' ;
+--------------------------+----------------------------+
| Variable_name | Value |
+--------------------------+----------------------------+
| character_set_client | latin1 |
| character_set_connection | latin1 |
| character_set_database | latin1 |
| character_set_filesystem | binary |
| character_set_results | latin1 |
| character_set_server | latin1 |
| character_set_system | utf8 |
| character_sets_dir | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
8 rows in set (0.01 sec)

# 运行容器 需要做数据挂载!
[root@localhost ~]# docker run -d -p 3306:3306 \
--privileged=true \
-v /home/mysql/conf:/etc/mysql/conf.d \
-v /home/mysql/data:/var/lib/mysql \
-v /home/mysql/log:/var/log/mysql \
-e MYSQL_ROOT_PASSWORD=123456 \
--name mysql01 mysql:5.7
#修改字符集
# 创建my.conf并填入以下内容
vi /home/mysql/conf/my.cnf
# 方法一
[client]
default_character_set=utf8
[mysqld]
collation_server = utf8_general_ci
character_set_server = uft8
# 方法二
[mysql]
default-character-set=utf8mb4
[mysqld]
character_set_server = utf8
init_connect='SET NAMES utf8'
lower_case_table_names=1
# 方法三
[root@localhost ~]# docker run -d -p 3306:3306 \
--privileged=true \
-v /home/mysql/conf:/etc/mysql/conf.d \
-v /home/mysql/data:/var/lib/mysql \
-v /home/mysql/log:/var/log/mysql \
-e MYSQL_ROOT_PASSWORD=123456 \
--name mysql01 mysql:5.7 \
--character-set-server=utf8mb4 \
--collation-server=utf8mb4_unicode_ci
##
新项目只考虑utf8mb4
  UTF-8 编码是一种变长的编码机制,可以用1~4个字节存储字符。

  因为历史遗留问题,MySQL 中的 utf8 编码并不是真正的 UTF-8,而是阉割版的,最长只有3个字节。当遇到占4个字节的 UTF-8 编码,例如 emoji 字符或者复杂的汉字,也就是我们通常在聊天时发的小黄脸表情,会导致存储异常。

  从 5.5.3 开始,MySQL 开始用 utf8mb4 编码来实现完整的 UTF-8,其中 mb4 表示 most bytes 4,最多占用4个字节,用来兼容四个字节的Unicode(万国码)。utf8mb4是utf8的一个扩展。从 8.0 之后,将会在某个版本开始用 utf8mb4 作为默认字符编码。
# 重启mysql02
docker restart mysql02

具名与匿名挂载

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# 查看卷的命令

# [root@localhost home]# docker volume --help

Usage: docker volume COMMAND

Manage volumes

Commands:
create Create a volume
inspect Display detailed information on one or more volumes
ls List volumes
prune Remove all unused local volumes
rm Remove one or more volumes

-v 容器内路径!
docker run -d -P

# 匿名挂载
[root@localhost home]# docker run -d -P --name nginx01 -v /etc/nginx nginx
# 具名挂载
# -v 卷名:容器内路径
[root@localhost home]# docker run -d -P --name nginx02 -v my-nginx:/etc/nginx nginx
# 查看挂载路径
[root@localhost home]# docker volume inspect my-nginx
[
{
"CreatedAt": "2022-06-28T22:46:09-04:00",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/my-nginx/_data",
"Name": "my-nginx",
"Options": null,
"Scope": "local"
}
]
# 所有的docker容器内的卷,没有自定义目录的情况下都是在/var/lib/docker/volumes/xxx/_data
1
2
3
4
5
6
7
8
9
10
11
# 如何确定是具名挂载还是匿名挂载,还是指定路径挂载!
-v 容器内路径 # 匿名挂载
-v 卷名:容器内路径 # 具名挂载
-v /宿主机路径:/容器内路径 # 指定路径挂载

# 通过 -v 容器内路径:ro rw 改变读写权限
ro readonly #只读
rw readwrite #读写
# 一旦这个设置容器权限,容器对我们挂载出来的内容就有先限定了!
docker run -d -P --name nginx02 -v my-nginx:/etc/nginx:ro nginx
docker run -d -P --name nginx02 -v my-nginx:/etc/nginx:rw nginx

初识Dockerfile

Dockerfile 就是用来构建 docker 镜像的构建文件 ! 命令脚本!

通过这个脚本可以生成镜像,镜像是一层一层的,脚本一个个的命令,每个命令都是一层!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 编写dockerfile脚本
[root@localhost docker-test-volume]# vi dockerfile1
[root@localhost docker-test-volume]# cat dockerfile1
FORM centos

VOLUME ["volume01","volume02"]

CMD echo "------end------"
CMD /bin/bash
# 构建镜像
[root@localhost docker-test-volume]# docker build -f dockerfile1 -t shawn/centos:1.0 .
-f 指定dockerfile文件
-t 指定镜像名以及版本
. 在当前目录生成

# 数据卷同步
docker run -it --name docker03 --volumes-from docker01 shawn/centos:1.0(镜像启动)

结论:

容器之间配置信息的传递,数据卷容器的生命周期一直持续到没有容器使用为止。

但是一旦你持久化到了本地,这个时候,本地的数据是不会删除的

DockerFile构建过程

基础知识

1、每个保留关键字(指令)都是必须是大写字母

2、执行从上到下顺序执行

3、#表示注释

4、每个指令都会创建提交一个新的镜像层,并提交!

1
2
3
4
5
可写容器(container)
镜像(tomcat)
镜像(jdk)
rootfs(基础镜像 centos/ubuntu)
bootfs

dockerfile是面向开发的,我们以后要发布项目,做镜像,就需要编写dockerfile文件,这个文件十分简单!

Docker镜像逐渐成为企业交付的标准,必须要掌握 !

步骤:开发 部署 运维 缺一不可 !

DockerFile:构建文件,定义了一切的步骤,源代码

DockerImages:通过DockerFile构建生成镜像,最终发布与运行的产品

Docker容器:容器就是镜像运行起来提供服务的

Dockerfile指令

1
2
3
4
5
6
7
8
9
10
11
12
FROM       # 基础镜像,一切从这里开始构建
MAINTAINER # 镜像是谁写的,姓名+邮箱
RUN # 镜像构建的时候需要运行的命令
ADD # 步骤:tomcat镜像,这个tomcat压缩包!添加内容
WORKDIR # 镜像的工作目录
VOLUME # 挂载的目录
EXPOSE # 保留端口配置
CMD # 指定容器启动的时候要运行的命令,只有最后一个会生效,可被替代
ENTRYPOINT # 指定容器启动的时候要运行的命令,可以追加命令
ONBUILD # 当构建一个被继承DockerFile 这个时候就会运行 ONBUILD 的指令。触发指令。
COPY # 类似ADD,将我们文件拷贝到镜像中
ENV # 构建的时候设置环境变量!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
FROM

功能为指定基础镜像,并且必须是第一条指令。

如果不以任何镜像为基础,那么写法为:FROM scratch。

同时意味着接下来所写的指令将作为镜像的第一层开始

语法:

FROM <image>
FROM <image>:<tag>
FROM <image>:<digest>
三种写法,其中<tag>和<digest> 是可选项,如果没有选择,那么默认值为latest

RUN

功能为运行指定的命令

RUN命令有两种格式

1. RUN <command>
2. RUN ["executable", "param1", "param2"]
第一种后边直接跟shell命令

在linux操作系统上默认 /bin/sh -c

在windows操作系统上默认 cmd /S /C

第二种是类似于函数调用。

可将executable理解成为可执行文件,后面就是两个参数。

两种写法比对:

RUN /bin/bash -c 'source $HOME/.bashrc; echo $HOME
RUN ["/bin/bash", "-c", "echo hello"]
注意:多行命令不要写多个RUN,原因是Dockerfile中每一个指令都会建立一层.

多少个RUN就构建了多少层镜像,会造成镜像的臃肿、多层,不仅仅增加了构件部署的时间,还容易出错。

RUN书写时的换行符是\

CMD

功能为容器启动时要运行的命令

语法有三种写法

1. CMD ["executable","param1","param2"]
2. CMD ["param1","param2"]
3. CMD command param1 param2
第三种比较好理解了,就时shell这种执行方式和写法

第一种和第二种其实都是可执行文件加上参数的形式

举例说明两种写法:

CMD [ "sh", "-c", "echo $HOME"
CMD [ "echo", "$HOME" ]
补充细节:这里边包括参数的一定要用双引号,就是",不能是单引号。千万不能写成单引号。

原因是参数传递后,docker解析的是一个JSON array

RUN & CMD

不要把RUN和CMD搞混了。

RUN是构件容器时就运行的命令以及提交运行结果

CMD是容器启动时执行的命令,在构件时并不运行,构件时紧紧指定了这个命令到底是个什么样子

LABEL

功能是为镜像指定标签

语法:

LABEL <key>=<value> <key>=<value> <key>=<value> ...
一个Dockerfile种可以有多个LABEL,如下:

LABEL "com.example.vendor"="ACME Incorporated"
LABEL com.example.label-with-value="foo"
LABEL version="1.0"
LABEL description="This text illustrates \
that label-values can span multiple lines."
但是并不建议这样写,最好就写成一行,如太长需要换行的话则使用\符号

如下:

LABEL multi.label1="value1" \
multi.label2="value2" \
other="value3"
说明:LABEL会继承基础镜像种的LABEL,如遇到key相同,则值覆盖

MAINTAINER

指定作者

语法:

MAINTAINER <name>
EXPOSE

功能为暴漏容器运行时的监听端口给外部

但是EXPOSE并不会使容器访问主机的端口

如果想使得容器与主机的端口有映射关系,必须在容器启动的时候加上 -P参数

ENV

功能为设置环境变量

语法有两种

1. ENV <key> <value>
2. ENV <key>=<value> ...
两者的区别就是第一种是一次设置一个,第二种是一次设置多个

ADD

一个复制命令,把文件复制到景象中。

如果把虚拟机与容器想象成两台linux服务器的话,那么这个命令就类似于scp,只是scp需要加用户名和密码的权限验证,而ADD不用。

语法如下:

1. ADD <src>... <dest>
2. ADD ["<src>",... "<dest>"]
<dest>路径的填写可以是容器内的绝对路径,也可以是相对于工作目录的相对路径

<src>可以是一个本地文件或者是一个本地压缩文件,还可以是一个url

如果把<src>写成一个url,那么ADD就类似于wget命令

如以下写法都是可以的:

ADD test relativeDir/
ADD test /relativeDir
ADD http://example.com/foobar /
尽量不要把<scr>写成一个文件夹,如果<src>是一个文件夹了,复制整个目录的内容,包括文件系统元数据

COPY

看这个名字就知道,又是一个复制命令

语法如下:

1. COPY <src>... <dest>
2. COPY ["<src>",... "<dest>"]
ADD的区别

COPY的<src>只能是本地文件,其他用法一致

ENTRYPOINT

功能是启动时的默认命令

语法如下:

1. ENTRYPOINT ["executable", "param1", "param2"]
2. ENTRYPOINT command param1 param2
如果从上到下看到这里的话,那么你应该对这两种语法很熟悉啦。

第二种就是写shell

第一种就是可执行文件加参数

CMD比较说明(这俩命令太像了,而且还可以配合使用):

1. 相同点:

只能写一条,如果写了多条,那么只有最后一条生效

容器启动时才运行,运行时机相同

2. 不同点:

ENTRYPOINT不会被运行的command覆盖,而CMD则会被覆盖

如果我们在Dockerfile种同时写了ENTRYPOINT和CMD,并且CMD指令不是一个完整的可执行命令,那么CMD指定的内容将会作为ENTRYPOINT的参数

如下:

FROM ubuntu
ENTRYPOINT ["top", "-b"]
CMD ["-c"]
如果我们在Dockerfile种同时写了ENTRYPOINT和CMD,并且CMD是一个完整的指令,那么它们两个会互相覆盖,谁在最后谁生效

如下:

FROM ubuntu
ENTRYPOINT ["top", "-b"]
CMD ls -al
那么将执行ls -al ,top -b不会执行。

Docker官方使用一张表格来展示了ENTRYPOINT 和CMD不同组合的执行情况

(下方表格来自docker官网)



VOLUME

可实现挂载功能,可以将内地文件夹或者其他容器种得文件夹挂在到这个容器种

语法为:

VOLUME ["/data"]


说明:

["/data"]可以是一个JsonArray ,也可以是多个值。所以如下几种写法都是正确的

VOLUME ["/var/log/"]
VOLUME /var/log
VOLUME /var/log /var/db
一般的使用场景为需要持久化存储数据时

容器使用的是AUFS,这种文件系统不能持久化数据,当容器关闭后,所有的更改都会丢失。

所以当数据需要持久化时用这个命令。

USER

设置启动容器的用户,可以是用户名或UID,所以,只有下面的两种写法是正确的

USER daemo
USER UID
注意:如果设置了容器以daemon用户去运行,那么RUN, CMD 和 ENTRYPOINT 都会以这个用户去运行

WORKDIR

语法:

WORKDIR /path/to/workdir
设置工作目录,对RUN,CMD,ENTRYPOINT,COPY,ADD生效。如果不存在则会创建,也可以设置多次。

如:

WORKDIR /a
WORKDIR b
WORKDIR c
RUN pwd
pwd执行的结果是/a/b/c

WORKDIR也可以解析环境变量

如:

ENV DIRPATH /path
WORKDIR $DIRPATH/$DIRNAME
RUN pwd
pwd的执行结果是/path/$DIRNAME

ARG

语法:

ARG <name>[=<default value>]
设置变量命令,ARG命令定义了一个变量,在docker build创建镜像的时候,使用 --build-arg <varname>=<value>来指定参数

如果用户在build镜像时指定了一个参数没有定义在Dockerfile种,那么将有一个Warning

提示如下:

[Warning] One or more build-args [foo] were not consumed.


我们可以定义一个或多个参数,如下:

FROM busybox
ARG user1
ARG buildno
...
也可以给参数一个默认值:

FROM busybox
ARG user1=someuser
ARG buildno=1
...
如果我们给了ARG定义的参数默认值,那么当build镜像时没有指定参数值,将会使用这个默认值

ONBUILD

语法:

ONBUILD [INSTRUCTION]
这个命令只对当前镜像的子镜像生效。

比如当前镜像为A,在Dockerfile种添加:

ONBUILD RUN ls -al
这个 ls -al 命令不会在A镜像构建或启动的时候执行

此时有一个镜像B是基于A镜像构建的,那么这个ls -al 命令会在B镜像构建的时候被执行。

STOPSIGNAL

语法:

STOPSIGNAL signal
STOPSIGNAL命令是的作用是当容器推出时给系统发送什么样的指令

HEALTHCHECK

容器健康状况检查命令

语法有两种:

1. HEALTHCHECK [OPTIONS] CMD command
2. HEALTHCHECK NONE
第一个的功能是在容器内部运行一个命令来检查容器的健康状况

第二个的功能是在基础镜像中取消健康检查命令

[OPTIONS]的选项支持以下三中选项:

--interval=DURATION 两次检查默认的时间间隔为30

--timeout=DURATION 健康检查命令运行超时时长,默认30

--retries=N 当连续失败指定次数后,则容器被认为是不健康的,状态为unhealthy,默认次数是3



注意:

HEALTHCHECK命令只能出现一次,如果出现了多次,只有最后一个生效。

CMD后边的命令的返回值决定了本次健康检查是否成功,具体的返回值如下:

0: success - 表示容器是健康的

1: unhealthy - 表示容器已经不能工作了

2: reserved - 保留值

例子:

HEALTHCHECK --interval=5m --timeout=3s \
CMD curl -f http://localhost/ || exit 1


健康检查命令是:curl -f http://localhost/ || exit 1

Docker network (容器网络)

Docker compose(容器编排)

Docker Swarm(集群)

CI/CD jenkins (流水线)

ansible (自动化工具,部署)

0%