Docker 实例
由于虚拟机存在这些缺点,Linux 发展出了另一种虚拟化技术:Linux 容器(Linux Containers,缩写为 LXC)。 Linux 容器不是模拟一个完整的操作系统,而是对进程进行隔离。或者说,在正常进程的外面套了一个保护层。对于容器里面的进程来说,它接触到的各种资源都是虚拟的,从而实现与底层系统的隔离。 由于容器是进程级别的,相比虚拟机有很多优势。 (1)启动快 容器里面的应用,直接就是底层系统的一个进程,而不是虚拟机内部的进程。所以,启动容器相当于启动本机的一个进程,而不是启动一个操作系统,速度就快很多。 (2)资源占用少 容器只占用需要的资源,不占用那些没有用到的资源;虚拟机由于是完整的操作系统,不可避免要占用所有资源。另外,多个容器可以共享资源,虚拟机都是独享资源。 (3)体积小 容器只要包含用到的组件即可,而虚拟机是整个操作系统的打包,所以容器文件比虚拟机文件要小很多。 总之,容器有点像轻量级的虚拟机,能够提供虚拟化的环境,但是成本开销小得多。
- ansible 学习基础
- Docker 安装 Nginx
- Docker 安装 MySQL
- 可视化部署说明
- Maven私服:Docker安装nexus3
- Docker 安装 ActiveMQ
- 使用 GitLab Runner 配置 CI/CD 流水线
- Docker 创建 Nginx 和 php-fpm环境
- Docker 安装 MongoDB
- Docker 安装 PHP
ansible 学习基础
ansible 基础
ansible, ansible-doc, ansible-galaxy, ansible-lint, ansible-playbook, ansible-pull, ansible-vault
管理节点
ssh映射: 10.44.111.115:179
安装常用工具
sudo yum install -y vim wget lrzsz screen
username root/develop
password 2019@eagle/develop
- ip: 172.17.163.179
- netmask 255.255.255.240
- gateway
- route 172.17.163.177
- DNS 172.17.163.177
控制管理节点安装 ansible
sudo yum install ansible -y
使用 ssh-keygen
生成 ssh key
并使用 ssh-copy-id
分发到 server
节点
[develop@localhost ~]$ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/home/develop/.ssh/id_rsa):
Created directory '/home/develop/.ssh'.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/develop/.ssh/id_rsa.
Your public key has been saved in /home/develop/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:i8laZFq8RAnOUEBdWLIy8LpDbZUiri9MbFmh+RKnUz4 develop@localhost.locald
The key's randomart image is:
+---[RSA 2048]----+
|..++++o |
| o =o+.. |
| .*.=oo |
|.=o*oo |
|ooXo * S |
|oX.E B + . |
|B o o * . |
|.+ o |
| .. . |
+----[SHA256]-----+
[develop@localhost ~]$ cat .ssh/id_rsa.pub
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDFCAJp1+ER36dn1HN92/e2VbFAex1bLvaKEqXyG07l7NmQ0hXsfLHHMFkaHgRiVKdRccNe1gFOvRmmApxTocm+6X/S+e6SRQUjTlnVlOLWpKG42MqaEnmfNYb10uWrRKboBVUpt4xCIvd41TDAyqSQq5lPPPFPkc5J7vs9DIc1C5Seuzl2epMRhLQ195QPntxjLeD/Pgt+f7TCt8Q7PAkYWFwkIjcozUtFTS69CHobiMec5xPhpfWDUb7El8yC8KVR7hcFeDEG/gkqaU5Hzgow96T182jZG8ujOwVJ9dltpKuWvFnKxavZqVcooiCyi3jXjI2oaY8kdOKvvxJjWhwH develop@localhost.localdomain
[develop@localhost ~]$
[develop@localhost ~]$ ssh-copy-id -i ~/.ssh/id_rsa.pub 172.17.163.181
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/home/develop/.ssh/id_rsa.pub"
The authenticity of host '172.17.163.181 (172.17.163.181)' can't be established.
ECDSA key fingerprint is SHA256:iVZEKj9NsHP/zhwdfu/gZLfV51LIsidtEhp2HpNg9k0.
ECDSA key fingerprint is MD5:54:99:0d:aa:e8:c5:8a:5e:f2:e6:a6:e9:4c:d6:db:ac.
Are you sure you want to continue connecting (yes/no)? yes
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
develop@172.17.163.181's password:
Number of key(s) added: 1
Now try logging into the machine, with: "ssh '172.17.163.181'"
and check to make sure that only the key(s) you wanted were added.
[develop@localhost ~]$ ssh 172.17.163.181
Last login: Sat Nov 2 14:00:59 2019 from gateway
[develop@localhost ~]$ exit
登出
Connection to 172.17.163.181 closed.
[develop@localhost ~]$
配置 ansible
文件
sudo vim /etc/ansible/ansible.cfg
sudo vim /etc/ansible/hosts
配置 host
sudo vim /etc/ansible/hosts
追加参数:
server-spring-cloud ansible_ssh_host=10.44.111.231 ansible_ssh_port=22 ansible_ssh_user=spring-cloud ansible_ssh_pass=spring-cloud
server-test-vars ansible_ssh_host=10.44.111.127 ansible_ssh_port=2222 ansible_ssh_user=develop ansible_ssh_pass=develop
[test]
172.17.163.179
172.17.163.181
172.17.163.186
172.17.163.184
[test:vars] # 属性
ansible_ssh_port=22
ansible_ssh_user=develop
ansible_ssh_pass=develop
[test:children] # 继承
10.44.111.127
server-centos-01 ansible_ssh_host=10.44.111.115 ansible_ssh_port=179 ansible_ssh_pass=develop
server-centos-02 ansible_ssh_host=10.44.111.115 ansible_ssh_port=181 ansible_ssh_pass=develop
server-ubuntu-01 ansible_ssh_host=10.44.111.115 ansible_ssh_port=190 ansible_ssh_pass=develop
server-ubuntu-02 ansible_ssh_host=10.44.111.115 ansible_ssh_port=189 ansible_ssh_pass=develop
inventory 内置参数
ansible_ssh_host # 要连接的主机名
ansible_ssh_port # 端口号默认是22
ansible_ssh_user # ssh连接时默认使用的用户名
ansible_ssh_pass # ssh连接时的密码
ansible_sudo_pass # 使用sudo连接用户是的密码
ansible_ssh_private_key_file # 秘钥文件如果不想使用ssh-agent管理时可以使用此选项
ansible_shell_type # shell的类型默认sh
ansible_connection # SSH 连接的类型: local , ssh , paramiko在 ansible 1.2 之前默认是 paramiko ,后来智能选择,优先使用基于 ControlPersist 的 ssh (支持的前提)
ansible_python _ interpreter #用来指定 python 解释器的路径,同样可以指定ruby 、perl 的路径
测试
ansible test -m shell -a 'echo "Hello Ansible.." && date'
172.17.163.186 | SUCCESS | rc=0 >>
Hello Ansible..
2019年 11月 02日 星期六 14:47:00 CST
172.17.163.184 | SUCCESS | rc=0 >>
Hello Ansible..
2019年 11月 02日 星期六 14:47:00 CST
172.17.163.181 | SUCCESS | rc=0 >>
Hello Ansible..
2019年 11月 02日 星期六 14:47:00 CST
172.17.163.179 | SUCCESS | rc=0 >>
Hello Ansible..
2019年 11月 02日 星期六 14:47:00 CST
[develop@localhost ~]$
动态 inventory
动态inventory的意思是所有的变量可以从外部获取,也就是说我们可以从CMDB以及zabbix系统拉取所有的主机信息然后使用ansible进行管理。引用inventory只需要把ansible.cfg文件中的inventory定义值改成一个执行脚本即可
#!/usr/bin/env python
# coding=utf-8
import json
masterIp = ['172.17.163.179']
slaveIp = ['172.17.163.181','172.17.163.186','172.17.163.184']
masterGroup = 'master'
slaveGroup = 'slave'
hostdata = {masterGroup:{"hosts":masterIp},slaveGroup:{"hosts":slaveIp}}
print json.dumps(hostdata,indent=4)
[develop@localhost ~]$ python inverti.py
{
"slave": {
"hosts": [
"172.17.163.181",
"172.17.163.186",
"172.17.163.184"
]
},
"master": {
"hosts": [
"172.17.163.179"
]
}
}
[root@vagrant-centos65 opt]# ansible -i inverti.py all -a 'date'
SSH password:
192.168.1.15 | SUCCESS | rc=0 >>
07:25:27 up 3:56, 3 users, load average: 0.00, 0.00, 0.00
192.168.1.110 | SUCCESS | rc=0 >>
07:25:27 up 7 min, 3 users, load average: 0.00, 0.02, 0.00
ping 模块
ansible test -m ping
setup模块
获取主机信息
ansible test -m setup
过滤
ansible test -m setup -a 'filter=ansible_default_ipv4'
ansible test -m setup -a 'filter=ansible_memory_mb'
ansible test -m setup -a 'filter=*mb'
参数
ansible_all_ipv4_addresses: 仅显示ipv4的信息。
ansible_devices: 仅显示磁盘设备信息。
ansible_distribution: 显示是什么系统,例: centos,suse等。
ansible_distribution_major_version: 显示是系统主版本。
ansible_distribution_version: 仅显示系统版本。
ansible_machine: 显示系统类型,例: 32位,还是64位。
ansible_eth0: 仅显示eth0的信息。
ansible_hostname: 仅显示主机名。
ansible_kernel: 仅显示内核版本。
ansible_lvm: 显示lvm相关信息。
ansible_memtotal_mb: 显示系统总内存。
ansible_memfree_mb: 显示可用系统内存。
ansible_memory_mb: 详细显示内存情况。
ansible_swaptotal_mb: 显示总的swap内存。
ansible_swapfree_mb: 显示swap内存的可用内存。
ansible_mounts: 显示系统磁盘挂载情况。
ansible_processor: 显示cpu个数(具体显示每个cpu的型号)。
ansible_processor_vcpus: 显示cpu个数(只显示总的个数)。
ansible_python_version: 显示python版本。
file 模块
https://docs.ansible.com/ansible/latest/cli/ansible.html
file模块可以帮助我们完成一些对文件的基本操作,比如,创建文件或目录、删除文件或目录、修改文件权限等
[develop@localhost ~]$ ansible test -m file -a 'src=/etc/fstab dest=/home/develop/fstab state=link'
172.17.163.186 | SUCCESS => {
"changed": true,
"dest": "/home/develop/fstab",
"gid": 1000,
"group": "develop",
"mode": "0777",
"owner": "develop",
"secontext": "unconfined_u:object_r:user_home_t:s0",
"size": 10,
"src": "/etc/fstab",
"state": "link",
"uid": 1000
}
172.17.163.184 | SUCCESS => {
"changed": true,
"dest": "/home/develop/fstab",
"gid": 1000,
"group": "develop",
"mode": "0777",
"owner": "develop",
"secontext": "unconfined_u:object_r:user_home_t:s0",
"size": 10,
"src": "/etc/fstab",
"state": "link",
"uid": 1000
}
172.17.163.181 | SUCCESS => {
"changed": true,
"dest": "/home/develop/fstab",
"gid": 1000,
"group": "develop",
"mode": "0777",
"owner": "develop",
"secontext": "unconfined_u:object_r:user_home_t:s0",
"size": 10,
"src": "/etc/fstab",
"state": "link",
"uid": 1000
}
172.17.163.179 | SUCCESS => {
"changed": true,
"dest": "/home/develop/fstab",
"gid": 1000,
"group": "develop",
"mode": "0777",
"owner": "develop",
"secontext": "unconfined_u:object_r:user_home_t:s0",
"size": 10,
"src": "/etc/fstab",
"state": "link",
"uid": 1000
}
[develop@localhost ~]$ ansible test -a 'ls -l'
172.17.163.181 | SUCCESS | rc=0 >>
总用量 0
lrwxrwxrwx. 1 develop develop 10 11月 2 16:42 fstab -> /etc/fstab
172.17.163.186 | SUCCESS | rc=0 >>
总用量 0
lrwxrwxrwx. 1 develop develop 10 11月 2 16:42 fstab -> /etc/fstab
172.17.163.184 | SUCCESS | rc=0 >>
总用量 0
lrwxrwxrwx. 1 develop develop 10 11月 2 16:42 fstab -> /etc/fstab
172.17.163.179 | SUCCESS | rc=0 >>
总用量 108
lrwxrwxrwx. 1 develop develop 10 11月 2 16:42 fstab -> /etc/fstab
-rwxrwxr-x. 1 develop develop 295 11月 2 15:42 inverti.py
-rw-rw-r--. 1 develop develop 102710 11月 2 16:26 sysinfo
[develop@localhost ~]$
[develop@localhost ~]$ ansible test -m file -a 'path=/home/develop/touch.txt state=touch'
172.17.163.186 | SUCCESS => {
"changed": true,
"dest": "/home/develop/touch.txt",
"gid": 1000,
"group": "develop",
"mode": "0664",
"owner": "develop",
"secontext": "unconfined_u:object_r:user_home_t:s0",
"size": 0,
"state": "file",
"uid": 1000
}
172.17.163.181 | SUCCESS => {
"changed": true,
"dest": "/home/develop/touch.txt",
"gid": 1000,
"group": "develop",
"mode": "0664",
"owner": "develop",
"secontext": "unconfined_u:object_r:user_home_t:s0",
"size": 0,
"state": "file",
"uid": 1000
}
172.17.163.184 | SUCCESS => {
"changed": true,
"dest": "/home/develop/touch.txt",
"gid": 1000,
"group": "develop",
"mode": "0664",
"owner": "develop",
"secontext": "unconfined_u:object_r:user_home_t:s0",
"size": 0,
"state": "file",
"uid": 1000
}
172.17.163.179 | SUCCESS => {
"changed": true,
"dest": "/home/develop/touch.txt",
"gid": 1000,
"group": "develop",
"mode": "0664",
"owner": "develop",
"secontext": "unconfined_u:object_r:user_home_t:s0",
"size": 0,
"state": "file",
"uid": 1000
}
[develop@localhost ~]$ ansible test -a 'ls -l'
172.17.163.184 | SUCCESS | rc=0 >>
总用量 0
lrwxrwxrwx. 1 develop develop 10 11月 2 16:42 fstab -> /etc/fstab
-rw-rw-r--. 1 develop develop 0 11月 2 16:45 touch.txt
172.17.163.186 | SUCCESS | rc=0 >>
总用量 0
lrwxrwxrwx. 1 develop develop 10 11月 2 16:42 fstab -> /etc/fstab
-rw-rw-r--. 1 develop develop 0 11月 2 16:45 touch.txt
172.17.163.181 | SUCCESS | rc=0 >>
总用量 0
lrwxrwxrwx. 1 develop develop 10 11月 2 16:42 fstab -> /etc/fstab
-rw-rw-r--. 1 develop develop 0 11月 2 16:45 touch.txt
172.17.163.179 | SUCCESS | rc=0 >>
总用量 108
lrwxrwxrwx. 1 develop develop 10 11月 2 16:42 fstab -> /etc/fstab
-rwxrwxr-x. 1 develop develop 295 11月 2 15:42 inverti.py
-rw-rw-r--. 1 develop develop 102710 11月 2 16:26 sysinfo
-rw-rw-r--. 1 develop develop 0 11月 2 16:45 touch.txt
[develop@localhost ~]$
参数
- force: 需要在两种情况下强制创建软链接,一种是源文件不存在但之后会建立的情况下;另一种是目标软链接已存在,需要先取消之前的软链,然后创建新的软链,有两个选项: yes|no
- group: 定义文件/目录的属组
- mode: 定义文件/目录的权限
- owner: 定义文件/目录的属主
- path: 必选项,定义文件/目录的路径
- recurse: 递归的设置文件的属性,只对目录有效
- src: 要被链接的源文件的路径,只应用于state=link的情况
- dest: 被链接到的路径,只应用于state=link的情况
- state:
- directory: 如果目录不存在,创建目录
- file: 即使文件不存在,也不会被创建
- link: 创建软链接
- hard: 创建硬链接
- touch: 如果文件不存在,则会创建一个新的文件,如果文件或目录已存在,则更新其最后修改时间
- absent: 删除目录、文件或者取消链接文件
copy模块
[develop@localhost ~]$ ansible test -m copy -a 'src=/home/develop/xxx dest=/home/develop/xxx owner=develop mode=0700'
172.17.163.184 | SUCCESS => {
"changed": true,
"checksum": "da39a3ee5e6b4b0d3255bfef95601890afd80709",
"gid": 1000,
"group": "develop",
"mode": "0700",
"owner": "develop",
"path": "/home/develop/xxx",
"secontext": "unconfined_u:object_r:user_home_t:s0",
"size": 0,
"state": "file",
"uid": 1000
}
172.17.163.181 | SUCCESS => {
"changed": true,
"checksum": "da39a3ee5e6b4b0d3255bfef95601890afd80709",
"gid": 1000,
"group": "develop",
"mode": "0700",
"owner": "develop",
"path": "/home/develop/xxx",
"secontext": "unconfined_u:object_r:user_home_t:s0",
"size": 0,
"state": "file",
"uid": 1000
}
172.17.163.186 | SUCCESS => {
"changed": true,
"checksum": "da39a3ee5e6b4b0d3255bfef95601890afd80709",
"gid": 1000,
"group": "develop",
"mode": "0700",
"owner": "develop",
"path": "/home/develop/xxx",
"secontext": "unconfined_u:object_r:user_home_t:s0",
"size": 0,
"state": "file",
"uid": 1000
}
172.17.163.179 | SUCCESS => {
"changed": true,
"checksum": "da39a3ee5e6b4b0d3255bfef95601890afd80709",
"gid": 1000,
"group": "develop",
"mode": "0700",
"owner": "develop",
"path": "/home/develop/xxx",
"secontext": "unconfined_u:object_r:user_home_t:s0",
"size": 0,
"state": "file",
"uid": 1000
}
[develop@localhost ~]$ ansible test -a 'ls -l'
172.17.163.181 | SUCCESS | rc=0 >>
总用量 0
lrwxrwxrwx. 1 develop develop 10 11月 2 16:42 fstab -> /etc/fstab
-rw-rw-r--. 1 develop develop 0 11月 2 16:45 touch.txt
-rwx------. 1 develop develop 0 11月 2 17:41 xxx
172.17.163.186 | SUCCESS | rc=0 >>
总用量 0
lrwxrwxrwx. 1 develop develop 10 11月 2 16:42 fstab -> /etc/fstab
-rw-rw-r--. 1 develop develop 0 11月 2 16:45 touch.txt
-rwx------. 1 develop develop 0 11月 2 17:41 xxx
172.17.163.184 | SUCCESS | rc=0 >>
总用量 0
lrwxrwxrwx. 1 develop develop 10 11月 2 16:42 fstab -> /etc/fstab
-rw-rw-r--. 1 develop develop 0 11月 2 16:45 touch.txt
-rwx------. 1 develop develop 0 11月 2 17:41 xxx
172.17.163.179 | SUCCESS | rc=0 >>
总用量 108
lrwxrwxrwx. 1 develop develop 10 11月 2 16:42 fstab -> /etc/fstab
-rwxrwxr-x. 1 develop develop 295 11月 2 15:42 inverti.py
-rw-rw-r--. 1 develop develop 102710 11月 2 16:26 sysinfo
-rw-rw-r--. 1 develop develop 0 11月 2 16:45 touch.txt
-rwx------. 1 develop develop 0 11月 2 17:34 xxx
[develop@localhost ~]$
名称 | 必选 | 默认值 | 可选值 | 备注 |
---|---|---|---|---|
backup | no | no | yes/no |
在覆盖之前将原文件备份,备份文件包含时间信息 |
content | no | 当用content 代替src 参数的时候,可以把文档的内容设置到特定的值 |
||
dest | yes | 目标绝对路径。如果src 是一个目录,dest 也必须是一个目录。如果dest是不存在的路径,并且如果dest 以/结尾或者src 是目录,则dest 被创建。如果src 和dest 是文件,如果dest 的父目录不存在,任务将失败 |
||
follow | no | no | yes/no |
是否遵循目的机器中的文件系统链接 |
force | no | yes | yes/no |
当内容不同于源时,将替换远程文件。设置为no ,则只有在目标不存在的情况下才会传输文件 |
group | no | 设置文件/目录的所属组,将被馈送到chown |
||
local_follow | no | yes | yes/no |
是否遵循本地机器中的文件系统链接 |
mode | no | 设置文件权限,模式实际上是八进制数字(如0644),少了前面的零可能会有意想不到的结果。从版本1.8开始,可以将模式指定为符号模式(例如u+rwx或u=rw,g=r,o=r) | ||
owner | no | 设置文件/目录的所属用户,将被馈送到chown | ||
remote_src(2.0+) | no | no | yes/no |
如果yes它会从目标机上搜索src文件 |
src | no | 将本地路径复制到远程服务器; 可以是绝对路径或相对的。如果是一个目录,它将被递归地复制。如果路径以/结尾,则只有该目录下内容被复制到目的地,如果没有使用/来结尾,则包含目录在内的整个内容全部复制 | ||
unsafe_writes | no | yes/no |
是否以不安全的方式进行,可能导致数据损坏 | |
validate | no | None | 复制前是否检验需要复制目的地的路径 |
service 模块
1、启动服务:
ansible test -m service -a "name=nginx state=started"
2、停止服务:
ansible test -m service -a "name=nginx state=stopped"
3、重启服务:
ansible test -m service -a "name=nginx state=restarted"
4、开机启动:
ansible test -m service -a "name=nginx enable=yes"
5、停止开机启动:
ansible test -m service -a "name=nginx enable=no"
6、带参数启动:
ansible test -m service -a "name=network state=restarted args=eth0"
name
参数:此参数用于指定需要操作的服务名称,比如nginx
。state
参数:此参数用于指定服务的状态,比如,我们想要启动远程主机中的 nginx,则可以将state
的值设置为started
;如果想要停止远程主机中的服务,则可以将state
的值设置为stopped
。此参数的可用值有started
、stopped
、restarted
、reloaded
。enabled
参数:此参数用于指定是否将服务设置为开机 启动项,设置为yes
表示将对应服务设置为开机启动,设置为no
表示不会开机启动。
. . . . . . . .
playbook
首先简单说明一下 playbook
, playbook
是什么呢?根本上说 playbook
和 shell
脚本没有任何的区别, playbook
就像 shell
一样,也是把一堆的命令组合起来,然后加入对应条件判断等等,在shell脚本中是一条一条的命令,而在 playbook
中是一个一个的 task
任务构成,每个 task
任务可以看做 shell
中的一条命令;shell脚本一般只是在当前服务器上执行,而 playbook
则是在不止一个服务器上执行,因此 playbook
需要在其中指定运行该 playbook
的服务器名。
playbook的语法结构
playbook
使用 yml
标记语言,这是一种标记语言,这种标记语言在文件的最开始需要使用三个“-
”来说明文件开始,然后使用缩进来说明代码块的范围。下面通过一个简易的实例,来说明playbook的语法。【实例来自官方文档】
--- #标记文件的开始
- hosts: webservers #指定该playbook在哪个服务器上执行
vars: #表示下面是定义的变量,
http_port: 80 #变量的形式,key: value,这里http_port是变量名,80是值
max_clients: 200
remote_user: root #指定远程的用户名,这里缩进和vars保持了一致,说明变量的代码块已经结束。
tasks: #下面构成playbook的tasks,每个task都有 - name: 开始,name指定该任务的名称。
- name: ensure apache is at the latest version #指定该任务的名称。
yum: pkg=httpd state=latest #yum说明要是用的模板名称,后面指定对应的参数,这两行结合起来就相当于一个shell命令。
- name: write the apache config file #每个task之间可以使用空行来做区分。
template: src=/srv/httpd.j2 dest=/etc/httpd.conf
#需要说明的是缩进的意义和python中缩进的意义是一样,是来区分代码块的。
- 核心元素
Tasks:任务,由模板定义的操作列表 Variables:变量 Templates:模板,即使用模板语法的文件 Handlers:处理器 ,当某条件满足时,触发执行的操作 Roles:角色
- hosts和users介绍
在playbook中的每一个play都可以选择在哪些服务器和以什么用户完成,hosts一行可以是一个主机组、主机、多个主机,中间以冒号分隔,可使用通配模式。其中remote_user表示执行的用户账号。
---
- hosts: test #指定主机组,可以是一个或多个组。
remote_user: root #指定远程主机执行的用户名
指定远程主机sudo切换用
# vim ping.yml
---
- hosts: test
remote_user: root
become: yes #2.6版本以后的参数,之前是sudo,意思为切换用户运行
become_user: mysql #指定sudo用户为mysql
执行playbook
# ansible-playbook ping.yml -K
- Tasks list 和
action
介绍
1:Play的主体部分是task列表, task 列表中的各任务按次序逐个在hosts中指定的主机上执行,即在所有主机上完成第一个任务后再开始第二个任务。 在运行playbook时(从上到下执行),如果一个host执行task失败,整个tasks都会回滚,请修正playbook 中的错误,然后重新执行即可。 Task的目的是使用指定的参数执行模块,而在模块参数中可以使用变量,模块执行时幂等的,这意味着多次执行是安全的,因为其结果一致。 2:每一个task必须有一个名称name,这样在运行playbook时,从其输出的任务执行信息中可以很好的辨别出是属于哪一个task的。如果没有定义name,‘action’的值将会用作输出信息中标记特定的task。 3:定义一个task,常见的格式:”module: options” 例如:yum: name=httpd 4:ansible的自带模块中,command模块和shell模块无需使用key=value格式
playbook基础使用
ansible-playbook playbook.yml [options]
-u REMOTE_USER, --user=REMOTE_USER
# ssh 连接的用户名
-k, --ask-pass
#ssh登录认证密码
-s, --sudo
#sudo 到root用户,相当于Linux系统下的sudo命令
-U SUDO_USER, --sudo-user=SUDO_USER
#sudo 到对应的用户
-K, --ask-sudo-pass #用户的密码(—sudo时使用)
-T TIMEOUT, --timeout=TIMEOUT
# ssh 连接超时,默认 10 秒
-C, --check # 指定该参数后,执行 playbook 文件不会真正去执行,而是模拟执行一遍,然后输出本次执行会对远程主机造成的修改
-e EXTRA_VARS, --extra-vars=EXTRA_VARS
# 设置额外的变量如:key=value 形式 或者 YAML or JSON,以空格分隔变量,或用多个-e
-f FORKS, --forks=FORKS # 进程并发处理,默认 5
-i INVENTORY, --inventory-file=INVENTORY
# 指定 hosts 文件路径,默认 default=/etc/ansible/hosts
-l SUBSET, --limit=SUBSET
# 指定一个 pattern,对- hosts:匹配到的主机再过滤一次
--list-hosts # 只打印有哪些主机会执行这个 playbook 文件,不是实际执行该 playbook
--list-tasks # 列出该 playbook 中会被执行的 task
--private-key=PRIVATE_KEY_FILE # 私钥路径
--step # 同一时间只执行一个 task,每个 task 执行前都会提示确认一遍
--syntax-check # 只检测 playbook 文件语法是否有问题,不会执行该 playbook
-t TAGS, --tags=TAGS #当 play 和 task 的 tag 为该参数指定的值时才执行,多个 tag 以逗号分隔
--skip-tags=SKIP_TAGS # 当 play 和 task 的 tag 不匹配该参数指定的值时,才执行
-v, --verbose #输出更详细的执行过程信息,-vvv可得到所有执行过程信息。
原文链接:https://www.imooc.com/article/22729
- 常用命令
- ansible-playbook [yaml文件名、也可以yml结尾]
- 例如:ansible-playbook a.yml
- 参数:
-k(–ask-pass) 用来交互输入ssh密码 -K(-ask-become-pass) 用来交互输入sudo密码 -u 指定用户
ansible-playbook a.yml --syntax-check #检查yaml文件的语法是否正确
ansible-playbook a.yml --list-task #检查tasks任务
ansible-playbook a.yml --list-hosts #检查生效的主机
ansible-playbook a.yml --start-at-task='Copy Nginx.conf' #指定从某个task开始运行
- 示例
# vim a.yml
---
- hosts: 192.168.200.129 //指定主机
remote_user: root //指定在被管理的主机上执行任务的用户
tasks: //任务列表↓
- name: disable selinux //任务名关闭防火墙
command: '/sbin/setenforce 0' //调用command模块 执行关闭防火墙命令
- name: start httpd //任务名 开启httpd
service: name=httpd state=started //调用service模块 开启httpd 服务
# ansible-playbook a.yml --syntax-check #检查yaml文件的语法是否正确
# ansible-playbook a.yml
- 综合练习
mkdir -p ansible-playbook/roles/nginx/tasks
cd ansible-playbook
touch site.yml
touch roles/nginx/tasks/main.yml
site.yml
---
- hosts: dev1
gather_facts: no
remote_user: develop
roles:
- nginx
roles/nginx/tasks/main.yml
---
- name: install nginx
yum: name=nginx state=present
- name: start service nginx
service: name=nginx state=restated
ansible-playbook site.yml --syntax-check
ansible-playbook roles/nginx/tasks/main.yml --syntax-check
ansible centos -m user -a 'name=gdtcs'
vim chgpwd.yml
---
- hosts: centos
gather_facts: false
remote_user: root
tasks:
- name: Change password
user: name={{ username }} password={{ passwd | password_hash('sha512') }} update_password=always
ansible-playbook chgpwd.yml -e "username=root passwd=root"
ansible centos -a 'yum install -y /root/docker/docker-ce-19.03.3-3.el7.x86_64.rpm'
Docker 安装 Nginx
Nginx 是一个高性能的 HTTP 和反向代理 web 服务器,同时也提供了 IMAP/POP3/SMTP 服务 。
1、查看可用的 Nginx 版本
访问 Nginx 镜像库地址: https://hub.docker.com/_/nginx?tab=tags。
可以通过 Sort by
查看其他版本的 Nginx
,默认是最新版本 nginx:latest
。
你也可以在下拉列表中找到其他你想要的版本:
此外,我们还可以用 docker search nginx
命令来查看可用版本:
$ docker search nginx
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
nginx Official build of Nginx. 3260 [OK]
jwilder/nginx-proxy Automated Nginx reverse proxy for docker c... 674 [OK]
richarvey/nginx-php-fpm Container running Nginx + PHP-FPM capable ... 207 [OK]
million12/nginx-php Nginx + PHP-FPM 5.5, 5.6, 7.0 (NG), CentOS... 67 [OK]
maxexcloo/nginx-php Docker framework container with Nginx and ... 57 [OK]
...
2、取最新版的 Nginx 镜像
这里我们拉取官方的最新版本的镜像:
$ docker pull nginx:latest
3、查看本地镜像
使用以下命令来查看是否已安装了 nginx:
$ docker images
在上图中可以看到我们已经安装了最新版本(latest)的 nginx 镜像。
4、运行容器
安装完成后,我们可以使用以下命令来运行 nginx 容器:
$ docker run --name nginx-test -p 8080:80 -d nginx
参数说明:
- --name nginx-test:容器名称。
- -p 8080:80: 端口进行映射,将本地 8080 端口映射到容器内部的 80 端口。
- -d nginx: 设置容器在在后台一直运行。
5、安装成功
最后我们可以通过浏览器可以直接访问 8080 端口的 nginx 服务:
Docker 安装 MySQL
MySQL 是世界上最受欢迎的开源数据库。凭借其可靠性、易用性和性能,MySQL 已成为 Web 应用程序的数据库优先选择。
1、查看可用的 MySQL 版本
访问 MySQL 镜像库地址:https://hub.docker.com/_/mysql?tab=tags 。
可以通过 Sort by
查看其他版本的 MySQL
,默认是最新版本 mysql:latest
。
你也可以在下拉列表中找到其他你想要的版本:
此外,我们还可以用 docker search mysql
命令来查看可用版本:
$ docker search mysql
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
mysql MySQL is a widely used, open-source relati... 2529 [OK]
mysql/mysql-server Optimized MySQL Server Docker images. Crea... 161 [OK]
centurylink/mysql Image containing mysql. Optimized to be li... 45 [OK]
sameersbn/mysql 36 [OK]
google/mysql MySQL server for Google Compute Engine 16 [OK]
appcontainers/mysql Centos/Debian Based Customizable MySQL Con... 8 [OK]
marvambass/mysql MySQL Server based on Ubuntu 14.04 6 [OK]
drupaldocker/mysql MySQL for Drupal 2 [OK]
azukiapp/mysql Docker image to run MySQL by Azuki - http:... 2 [OK]
...
2、拉取 MySQL 镜像
这里我们拉取官方的最新版本的镜像:
$ docker pull mysql:latest
3、查看本地镜像
使用以下命令来查看是否已安装了 mysql:
$ docker images
在上图中可以看到我们已经安装了最新版本(latest)的 mysql 镜像。
4、运行容器
安装完成后,我们可以使用以下命令来运行 mysql 容器:
$ docker run -itd --name mysql-test -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 mysql
参数说明:
- -p 3306:3306 :映射容器服务的 3306 端口到宿主机的 3306 端口,外部主机可以直接通过
宿主机ip:3306
访问到 MySQL 的服务。 - MYSQL_ROOT_PASSWORD=123456:设置 MySQL 服务 root 用户的密码。
5、安装成功
通过 docker ps
命令查看是否安装成功:
本机可以通过 root
和密码 123456
访问 MySQL
服务。
# 查看已启动的服务
systemctl list-units --type=service
# 查看是否设置开机启动
systemctl list-unit-files | grep enable
# 设置开机启动
systemctl enable docker.service
# 关闭开机启动
systemctl disable docker.service
docker image pull mysql:5.7.28
# docker容器设置自动启动
# 启动时加--restart=always
docker run -id --restart=always -e MYSQL_ROOT_PASSWORD=2019@eagle --name mysql -v /mysql/data:/var/lib/mysql -v /etc/localtime:/etc/localtime -p 3306:3306 mysql:5.7.28
# 如果已经过运行的项目
docker container update --restart=always mysql
no 默认策略,在容器退出时不重启容器
on-failure 在容器非正常退出时(退出状态非0),才会重启容器
on-failure:3 在容器非正常退出时重启容器,最多重启3次
always 在容器退出时总是重启容器
unless-stopped 在容器退出时总是重启容器,但是不考虑在Docker守护进程启动时就已经停止了的容器
Flag Description
no 不自动重启容器. (默认value)
on-failure 容器发生error而退出(容器退出状态不为0)重启容器
unless-stopped 在容器已经stop掉或Docker stoped/restarted的时候才重启容器
always 在容器已经stop掉或Docker stoped/restarted的时候才重启容器
可视化部署说明
将已经准备好的Hyper-V虚拟机导入
本步骤不做特殊说明,按提示操作即可
本虚拟机中安装了
docker
服务及常用的image
并配置了开机启动; 安装了基本的常用工具:vim
screen
wget
curl
lrzsz
等
已安装的 docker
镜像
REPOSITORY TAG IMAGE ID CREATED SIZE
tomcat 8.5.50-jdk8 6fa48e047721 3 days ago 507MB
tomcat 8.5.50-jdk11 f425297f8aa7 3 days ago 624MB
rabbitmq 3.8.1 843e6712e712 6 weeks ago 150MB
openjdk 11 a7e47afa852b 8 weeks ago 605MB
mysql 5.7.28 cd3ed0dfff7e 2 months ago 437MB
nginx 1.16.1 b50b08c36b60 2 months ago 126MB
openjdk 8 e8d00769c8a8 3 months ago 488MB
ansible/ansible centos7 0731001e75a9 2 years ago 669MB
配置虚拟机系统
虚拟机开机之后默认的 IP
为 10.44.111.123
子网掩码为 255.255.255.0
( 24
) 网关为 10.44.111.1
需要将以上网络配置为当前网络的信息,以下为操作步骤
- 启动虚拟机并连接虚拟机
- 输入用户名/密码:
develop
/develop
- 配置网络文件,默认的网卡为
eth0
[develop@adsl-172-10-0-101 ~]$ sudo vim /etc/sysconfig/network-scripts/ifcfg-eth0 # 如需要输入密码,请按第二步密码输入 TYPE="Ethernet" PROXY_METHOD="none" BROWSER_ONLY="no" BOOTPROTO="none" DEFROUTE="yes" IPV4_FAILURE_FATAL="no" IPV6INIT="yes" IPV6_AUTOCONF="yes" IPV6_DEFROUTE="yes" IPV6_FAILURE_FATAL="no" IPV6_ADDR_GEN_MODE="stable-privacy" NAME="eth0" UUID="d4c2b640-0314-44ff-83f6-9926d49fefe1" DEVICE="eth0" ONBOOT="yes" IPADDR="10.44.111.123" PREFIX="24" GATEWAY="10.44.111.1" DNS1="180.76.76.76" IPV6_PRIVACY="no" # 通常情况下需要修改IP, 子网掩码, 网关; 分别为: IPADDR PREFIX GATEWAY # 修改完成之后按 Shift + : ---> wq ---> Enter
- 重启网络服务
# 重启网络服务 sudo systemctl restart network # 查看ip ip a
说明
用户名 | 密码 |
---|---|
root | 2019@eagle |
develop | develop |
nginx-html-path:
/home/develop/html/
关键字
以下使用的 $PWD
均为当前目录, 也就是: /home/develop
部署 nginx
前端服务
网络配置完成之后即可通过 ssh
方式连接虚拟机,并把程序上传至虚拟机服务器中;以下使用 XShell
工具操作
- 运行
docker
中的nginx
镜像docker run -id -v $PWD/html:/usr/share/nginx/html --name nginx -p 80:80 --restart=always nginx:1.16.1 # -id 创建一个以交互模式运行容器,后台运行 # -v 绑定数据卷,这里将nginx中页面挂载到当前目录的 html 中;也可以将配置目录和文件(/etc/nginx/nginx.conf)、日志目录(/var/log/nginx/) 挂载到宿主机上 # --name nginx 为容器指定一个名称 # -p 指定端口映射 # --restart=always 开机启动
- 配置防火墙
[develop@adsl-172-10-0-101 ~]$ sudo firewall-cmd --zone=public --add-port=80/tcp --permanent [develop@adsl-172-10-0-101 ~]$ sudo firewall-cmd --reload # 重启 `nginx` 容器 [develop@adsl-172-10-0-101 ~]$ docker container restart nginx
- 修改所属用户或用户组
[develop@adsl-172-10-0-101 ~]$ sudo chown develop:develop $PWD/html
- 添加测试文件
[develop@adsl-172-10-0-101 ~]$ touch $PWD/html/index.html
- 测试
[develop@adsl-172-10-0-101 ~]$ wget 127.0.0.1 --2019-12-17 15:47:06-- http://127.0.0.1/ 正在连接 127.0.0.1:80... 已连接。 已发出 HTTP 请求,正在等待回应... 200 OK 长度:0 [text/html] 正在保存至: “index.html” [ <=> ] 0 --.-K/s 用时 0s 2019-12-17 15:47:06 (0.00 B/s) - 已保存 “index.html” [0/0]) [develop@adsl-172-10-0-101 ~]$ # 表示成功
- 部署程序
将程序代码
display-page.zip
拷贝到$PWD/html
目录中并解压[develop@adsl-172-10-0-101 ~]$ mv display-page.zip $PWD/html [develop@adsl-172-10-0-101 ~]$ cd $PWD/html && unzip display-page.zip
部署 mysql
数据库服务
- 运行 docker 中的 mysql 镜像
docker run -id --restart=always -e MYSQL_ROOT_PASSWORD=2019@eagle --name mysql -v /mysql/data:/var/lib/mysql -v /etc/localtime:/etc/localtime -p 3306:3306 mysql:5.7.28 # -e 设置环境变量 mysql密码为 2019@eagle
- 配置防火墙
[develop@adsl-172-10-0-101 ~]$ sudo firewall-cmd --zone=public --add-port=3306/tcp --permanent [develop@adsl-172-10-0-101 ~]$ sudo firewall-cmd --reload # 重启 `mysql` 容器 [develop@adsl-172-10-0-101 ~]$ docker container restart mysql
- 测试
mysql
连接
netstat -ntulp | grep 80 netstat -ntplu | grep docker
Maven私服:Docker安装nexus3
Maven私服:Docker安装nexus3
查找nexus3镜像
develop@ubuntu:~$ docker search nexus3
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
sonatype/nexus3 Sonatype Nexus Repository Manager 3 697
shifudao/nexus3 clone from nexus3 image but based from openj… 4 [OK]
madmuffin/nexus3 Sonatype Nexus3 Milestone7 docker image 2 [OK]
home1oss/nexus3 An auto configured nexus3 2 [OK]
fxinnovation/nexus3 Sonatype Nexus 3 in a container 1 [OK]
flavioaiello/nexus3 Production ready lightweight Nexus3 with API… 1 [OK]
cirepo/nexus3 An auto configured nexus3 1 [OK]
alvindaiyan/nexus3-azure-appservice 1
dwolla/nexus3-crowd Nexus3 with nexus3-crowd-plugin installed 0 [OK]
joshdvir/nexus3 nexus3 0 [OK]
freckleiot/nexus3-oss A Sonatype Nexus3 OSS image which makes it e… 0 [OK]
sdase/nexus3-base-image An opinionated nexus3 docker image, based on… 0 [OK]
fgbulsoni/nexus3 My fork of the Sonatype/Nexus3 image, with a… 0
stocksoftware/nexus3 A nexus3 docker instance 0 [OK]
azaa1/nexus3 Sonyatype Nexus Repository Manager 3 0
salte/nexus3 Extends the Sonatype nexus3 Docker image by … 0 [OK]
mritd/nexus3 nexus3 0 [OK]
desiato/nexus3-ssl Sonatype Nexus 3 with SSL/TLS support. 0 [OK]
lokkju/nexus3-github-auth Sonatype Nexus 3 with Github authentication … 0 [OK]
jullyannem/nexus3 Custom image for sonatype/nexus3 0
bigseasre/nexus3 mirror of the original nexus3 dockerfile 0
darthhater/nexus3 A series of example Dockerfiles and images f… 0 [OK]
amribrahim00/nexus3 0
enieuw/nexus3-oss nexus3-oss 0 [OK]
nasajon/nexus3 Nexus3 0 [OK]
拉取nexus3镜像
develop@ubuntu:~$ docker search sonatype/nexus3
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
develop@ubuntu:~$ docker image pull sonatype/nexus3
Using default tag: latest
latest: Pulling from sonatype/nexus3
c65691897a4d: Pull complete
641d7cc5cbc4: Pull complete
c508b13320cd: Pull complete
79e3bf9d3132: Pull complete
Digest: sha256:2c33632ccd8f8c5f9023a3d7f5f541e271833e402219f8c5a83a29d1721457ca
Status: Downloaded newer image for sonatype/nexus3:latest
docker.io/sonatype/nexus3:latest
查看镜像
develop@ubuntu:~$ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
tomcat 8.5.47 882487b8be1d 12 days ago 507MB
ubuntu 16.04 b9409899fe86 12 days ago 122MB
ubuntu 18.04 cf0f3ca922e0 12 days ago 64.2MB
node 10.16.3 a68faf70e589 13 days ago 904MB
mysql 5.7.28 cd3ed0dfff7e 13 days ago 437MB
nginx 1.17.4 5a9061639d0a 13 days ago 126MB
redis 5.0.6 de25a81a5a0b 2 weeks ago 98.2MB
sonatype/nexus3 latest 8eb898be2a53 3 weeks ago 611MB
centos 8 0f3e07c0138f 4 weeks ago 220MB
busybox latest 19485c79a9bb 8 weeks ago 1.22MB
centos 7 67fa590cfc1c 2 months ago 202MB
centos 7.6.1810 f1cb7c7d58b7 7 months ago 202MB
centos 6 d0957ffdf8a2 7 months ago 194MB
查看docker nexus3 暴露端口
第一种方式 history
develop@ubuntu:~$ docker image history sonatype/nexus3:latest
IMAGE CREATED CREATED BY SIZE COMMENT
8eb898be2a53 3 weeks ago /bin/sh -c #(nop) CMD ["sh" "-c" "${SONATYP… 0B
<missing> 3 weeks ago /bin/sh -c #(nop) ENV INSTALL4J_ADD_VM_PARA… 0B
<missing> 3 weeks ago /bin/sh -c #(nop) USER nexus 0B
<missing> 3 weeks ago /bin/sh -c #(nop) EXPOSE 8081 0B
<missing> 3 weeks ago /bin/sh -c #(nop) VOLUME [/nexus-data] 0B
<missing> 3 weeks ago |5 NEXUS_DOWNLOAD_SHA256_HASH=7a2e62848abeb0… 403MB
<missing> 3 weeks ago /bin/sh -c #(nop) ADD file:96a8726e4f3ee18b6… 1.97kB
<missing> 3 weeks ago /bin/sh -c #(nop) ARG NEXUS_REPOSITORY_MANA… 0B
<missing> 3 weeks ago /bin/sh -c #(nop) ARG NEXUS_REPOSITORY_MANA… 0B
<missing> 3 weeks ago /bin/sh -c #(nop) ENV NEXUS_HOME=/opt/sonat… 0B
<missing> 3 weeks ago /bin/sh -c #(nop) ENV SONATYPE_DIR=/opt/son… 0B
<missing> 3 weeks ago /bin/sh -c #(nop) ARG NEXUS_DOWNLOAD_SHA256… 0B
<missing> 3 weeks ago /bin/sh -c #(nop) ARG NEXUS_DOWNLOAD_URL=ht… 0B
<missing> 3 weeks ago /bin/sh -c #(nop) ARG NEXUS_VERSION=3.19.1-… 0B
<missing> 3 weeks ago /bin/sh -c #(nop) LABEL vendor=Sonatype mai… 0B
<missing> 6 weeks ago 3.55kB
<missing> 6 weeks ago 208MB Imported from -
第二种方式 inspect
develop@ubuntu:~$ docker image inspect sonatype/nexus3:latest
[
{
"Id": "sha256:8eb898be2a53434ed2310948ef1d4eb52d8298d400f0414d1fc5448cb10c1dc1",
"RepoTags": [
"sonatype/nexus3:latest"
],
"RepoDigests": [
"sonatype/nexus3@sha256:2c33632ccd8f8c5f9023a3d7f5f541e271833e402219f8c5a83a29d1721457ca"
],
"Parent": "",
"Comment": "",
"Created": "2019-10-09T16:17:15.370913182Z",
"Container": "e313220b483cfb870091d005efa119f8349d671b132191eff68523eb8a0412fe",
"ContainerConfig": {
"Hostname": "a3a96c4a2d45",
"Domainname": "",
"User": "nexus",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"ExposedPorts": {
"8081/tcp": {}
},
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"container=oci",
"SONATYPE_DIR=/opt/sonatype",
"NEXUS_HOME=/opt/sonatype/nexus",
"NEXUS_DATA=/nexus-data",
"NEXUS_CONTEXT=",
"SONATYPE_WORK=/opt/sonatype/sonatype-work",
"DOCKER_TYPE=rh-docker",
"INSTALL4J_ADD_VM_PARAMS=-Xms1200m -Xmx1200m -XX:MaxDirectMemorySize=2g -Djava.util.prefs.userRoot=/nexus-data/javaprefs"
],
"Cmd": [
"/bin/sh",
"-c",
"#(nop) ",
"CMD [\"sh\" \"-c\" \"${SONATYPE_DIR}/start-nexus-repository-manager.sh\"]"
],
"ArgsEscaped": true,
"Image": "sha256:4394c38c7fba645a92c4f96d71f05c9dcee3cd2259e7a45e69a655cafd775db4",
"Volumes": {
"/nexus-data": {}
},
"WorkingDir": "",
"Entrypoint": null,
"OnBuild": [],
"Labels": {
"architecture": "x86_64",
"authoritative-source-url": "registry.access.redhat.com",
"build-date": "2019-09-16T12:28:55.971236",
"com.redhat.build-host": "cpt-1001.osbs.prod.upshift.rdu2.redhat.com",
"com.redhat.component": "ubi8-container",
"com.redhat.license_terms": "https://www.redhat.com/en/about/red-hat-end-user-license-agreements#UBI",
"com.sonatype.license": "Apache License, Version 2.0",
"com.sonatype.name": "Nexus Repository Manager base image",
"description": "The Universal Base Image is designed and engineered to be the base layer for all of your containerized applications, middleware and utilities. This base image is freely redistributable, but Red Hat only supports Red Hat technologies through subscriptions for Red Hat products. This image is maintained by Red Hat and updated regularly.",
"distribution-scope": "public",
"io.k8s.description": "The Universal Base Image is designed and engineered to be the base layer for all of your containerized applications, middleware and utilities. This base image is freely redistributable, but Red Hat only supports Red Hat technologies through subscriptions for Red Hat products. This image is maintained by Red Hat and updated regularly.",
"io.k8s.display-name": "Red Hat Universal Base Image 8",
"io.openshift.expose-services": "",
"io.openshift.tags": "base rhel8",
"maintainer": "Sonatype <cloud-ops@sonatype.com>",
"name": "ubi8",
"release": "208",
"summary": "Provides the latest release of Red Hat Universal Base Image 8.",
"url": "https://access.redhat.com/containers/#/registry.access.redhat.com/ubi8/images/8.0-208",
"vcs-ref": "592956edf47ff0ce45123f240898eabb469ac836",
"vcs-type": "git",
"vendor": "Sonatype",
"version": "8.0"
}
},
"DockerVersion": "18.09.6",
"Author": "",
"Config": {
"Hostname": "a3a96c4a2d45",
"Domainname": "",
"User": "nexus",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"ExposedPorts": {
"8081/tcp": {}
},
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"container=oci",
"SONATYPE_DIR=/opt/sonatype",
"NEXUS_HOME=/opt/sonatype/nexus",
"NEXUS_DATA=/nexus-data",
"NEXUS_CONTEXT=",
"SONATYPE_WORK=/opt/sonatype/sonatype-work",
"DOCKER_TYPE=rh-docker",
"INSTALL4J_ADD_VM_PARAMS=-Xms1200m -Xmx1200m -XX:MaxDirectMemorySize=2g -Djava.util.prefs.userRoot=/nexus-data/javaprefs"
],
"Cmd": [
"sh",
"-c",
"${SONATYPE_DIR}/start-nexus-repository-manager.sh"
],
"ArgsEscaped": true,
"Image": "sha256:4394c38c7fba645a92c4f96d71f05c9dcee3cd2259e7a45e69a655cafd775db4",
"Volumes": {
"/nexus-data": {}
},
"WorkingDir": "",
"Entrypoint": null,
"OnBuild": [],
"Labels": {
"architecture": "x86_64",
"authoritative-source-url": "registry.access.redhat.com",
"build-date": "2019-09-16T12:28:55.971236",
"com.redhat.build-host": "cpt-1001.osbs.prod.upshift.rdu2.redhat.com",
"com.redhat.component": "ubi8-container",
"com.redhat.license_terms": "https://www.redhat.com/en/about/red-hat-end-user-license-agreements#UBI",
"com.sonatype.license": "Apache License, Version 2.0",
"com.sonatype.name": "Nexus Repository Manager base image",
"description": "The Universal Base Image is designed and engineered to be the base layer for all of your containerized applications, middleware and utilities. This base image is freely redistributable, but Red Hat only supports Red Hat technologies through subscriptions for Red Hat products. This image is maintained by Red Hat and updated regularly.",
"distribution-scope": "public",
"io.k8s.description": "The Universal Base Image is designed and engineered to be the base layer for all of your containerized applications, middleware and utilities. This base image is freely redistributable, but Red Hat only supports Red Hat technologies through subscriptions for Red Hat products. This image is maintained by Red Hat and updated regularly.",
"io.k8s.display-name": "Red Hat Universal Base Image 8",
"io.openshift.expose-services": "",
"io.openshift.tags": "base rhel8",
"maintainer": "Sonatype <cloud-ops@sonatype.com>",
"name": "ubi8",
"release": "208",
"summary": "Provides the latest release of Red Hat Universal Base Image 8.",
"url": "https://access.redhat.com/containers/#/registry.access.redhat.com/ubi8/images/8.0-208",
"vcs-ref": "592956edf47ff0ce45123f240898eabb469ac836",
"vcs-type": "git",
"vendor": "Sonatype",
"version": "8.0"
}
},
"Architecture": "amd64",
"Os": "linux",
"Size": 610620831,
"VirtualSize": 610620831,
"GraphDriver": {
"Data": {
"LowerDir": "/var/lib/docker/overlay2/1efc97c10191da75fce41b0da8f423b59a5d96ffb89e7b07d012ee1a64864c51/diff:/var/lib/docker/overlay2/aee2ffe75b92dc90ab960b6e7feb49474fabe44bed6529116a554a3ebf6e5c73/diff:/var/lib/docker/overlay2/5125a1abfcbbea486e7c0df81a40681797c24ff30e3bdbca477f0cb06964266d/diff",
"MergedDir": "/var/lib/docker/overlay2/9ab78069111e94162980242cf5beb5a0591b29139ffb3bb21cac942a5a7ed14d/merged",
"UpperDir": "/var/lib/docker/overlay2/9ab78069111e94162980242cf5beb5a0591b29139ffb3bb21cac942a5a7ed14d/diff",
"WorkDir": "/var/lib/docker/overlay2/9ab78069111e94162980242cf5beb5a0591b29139ffb3bb21cac942a5a7ed14d/work"
},
"Name": "overlay2"
},
"RootFS": {
"Type": "layers",
"Layers": [
"sha256:6866631b657ec5662f4faf948c771d9585a8ea005b1373360ada0a4507cd5c09",
"sha256:48905dae401049ac43befb4f900a6aa0b5d30119db1f0cd0cca92980e0040ad0",
"sha256:1e090454f289654b091f9c9c874c269968a8367657b0f2da1487d456c690fe13",
"sha256:ca9d13755b9ef70fc1e01592d491fecd5661950812aa5bf1e0f4379254551c6b"
]
},
"Metadata": {
"LastTagTime": "0001-01-01T00:00:00Z"
}
}
]
运行nexus容器
develop@ubuntu:~$ docker run -id --privileged=true --name nexus3 --restart=always -p 8081:8081 -v /data/nexus3/nexus-data/:/nexus-data sonatype/nexus3:latest
6cea2db83fc4f708a5278e01a1cc6347f05b065102b3c85f4d49ae5ca3b6e6b3
解释:
8081 端口是 nexus 的服务访问端口 8082 端口是用于 host 镜像仓库的服务端口 8083 端口用户 group 镜像仓库的服务端口
-id 创建守护式容器 --privileged=true 授予root权限(挂载多级目录必须为true,否则容器访问宿主机权限不足) --name=名字 给你的容器起个名字 -p 宿主机端口:容器端口映射 -v 宿主机目录:容器目录 目录挂载
查看容器日志
develop@ubuntu:~$ docker container logs -f nexus3
2019-10-31 03:51:06,996+0000 INFO [FelixStartLevel] *SYSTEM org.sonatype.nexus.pax.logging.NexusLogActivator - start
2019-10-31 03:51:07,702+0000 INFO [FelixStartLevel] *SYSTEM org.sonatype.nexus.features.internal.FeaturesWrapper - Fast FeaturesService starting
2019-10-31 03:51:09,267+0000 WARN [FelixStartLevel] *SYSTEM uk.org.lidalia.sysoutslf4j.context.SysOutOverSLF4JInitialiser - Your logging framework class org.ops4j.pax.logging.slf4j.Slf4jLogger is not known - if it needs access to the standard println methods on the console you will need to register it by calling registerLoggingSystemPackage
2019-10-31 03:51:09,270+0000 INFO [FelixStartLevel] *SYSTEM uk.org.lidalia.sysoutslf4j.context.SysOutOverSLF4J - Package org.ops4j.pax.logging.slf4j registered; all classes within it or subpackages of it will be allowed to print to System.out and System.err
2019-10-31 03:51:09,277+0000 INFO [FelixStartLevel] *SYSTEM uk.org.lidalia.sysoutslf4j.context.SysOutOverSLF4J - Replaced standard System.out and System.err PrintStreams with SLF4JPrintStreams
2019-10-31 03:51:09,279+0000 INFO [FelixStartLevel] *SYSTEM uk.org.lidalia.sysoutslf4j.context.SysOutOverSLF4J - Redirected System.out and System.err to SLF4J for this context
...
注意: 运行容器后访问主机+配置的宿主机映射端口无反应时,请稍等几分钟(视配置时间长短不一),等待nexus3完成初始化才能访问成功
访问nexus3
确保正常启动后 使用浏览器访问http://服务器ip:8081
/nexus-data/admin.password
登录配置
sudo cat /var/lib/docker/volumes/[volume_id]/_data/admin.password
点击右上角登录 账号密码:admin/[admin123]
查看仓库
登录后点击设置界面 选择Repositories,点击Create repository
选择仓库类型 这里选择hosted类型
配置仓库 该仓库指定一个唯一的名称、HTTP的端口、允许交互的API等
Docker 安装 ActiveMQ
搜索 ActiveMQ 镜像
docker search activemq
获取 ActiveMQ 镜像
docker pull webcenter/activemq
查看本地镜像
docker image ls
docker 启动 ActiveMQ 命令
docker run --name activemq \
-p 8161:8161 \
-p 1883:1883 \
-p 5672:5672 \
-p 61613:61613 \
-p 61614:61614 \
-p 61616:61616 \
-d webcenter/activemq
* 8161 是 web 页面管理端口(对外映射为8161)
* 1883 是 mqtt 使用端口(对外映射为1883)
* 5672 是 amcp 使用端口(对外映射为5672)
* 61613 是 stomp 使用端口(对外映射为61613)
* 61614 是 ws 使用端口(对外映射为61614)
* 61616 是 activemq 的容器使用端口(映射为61616)
* 8161 是 web 页面管理端口(对外映射为8161)
使用 docker ps 查看 ActiveMQ 已经运行了
使用 docker exec -it activemq /bin/bash 进入 ActiveMQ
访问
访问: http://ip:8161
默认用户:admin
默认密码:admin
使用 GitLab Runner 配置 CI/CD 流水线
使用 GitLab Runner 配置 CI/CD 流水线
前言
本文以实际例子介绍如何使用 GitLab Runner
配置 CI/CD
流水线,实现持续集成和持续交付。
安装配置 Runner
.gitlab-ci.yml
文件中定义的作业运行在 Runner 中。 Runner 需要通过网络访问 GitLab.
虽然 Runner 和 GitLab 可以安装在一台机器上,但不推荐这么做。
Runner 可以由多个项目中共享,但出于安全等方面的原因,一个项目或一组项目最好有专门的服务器、虚拟机或容器运行 Runner.
安装配置的官方文档见公司 GitLab 服务器中相关帮助。
安装
各种平台下的安装方法详见官方安装帮助文档。
RHEL/CentOS/Fedora
# For RHEL/CentOS/Fedora
curl -L https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.rpm.sh | sudo bash
# For RHEL/CentOS/Fedora
sudo yum install gitlab-runner
详见官方安装帮助文档。
配置
Step1: 获取注册令牌 (token)
以配置 Specific Runners 为例,在 GitLab 实例中,进入 项目设置 » CI/CD 页面,展开 Runner 可以获取项目的注册令牌。在这个页面也可以修改 Runner 和 CI/CD 的一些配置。
例如,对于 vue-element-admin 这个项目,可以转到这个链接。
泄露注册令牌可能会产生一些安全问题,故应妥善保管。万一泄露,可在本页面重置注册令牌。
Step2: 规划 Executors
Shell
Shell 的优势是灵活、调试简单,但一些手工操作并不能从代码中体现出来。在项目初期可以考虑这种方式。
Docker
Docker 是应用最广的方式,可以适应各种类型程序的编译打包。
Step3: 注册
除了 Executors, 在注册 Runner 的过程中还需要考虑命名、标签等,不同平台的注册方法也略有不同,详见官方文档。
Linux
- 运行命令
sudo gitlab-runner register
- 按提示输入 GitLab instance URL, URL 可从前面复制注册令牌的页面复制
Please enter the gitlab-ci coordinator URL (e.g. https://gitlab.com/):
https://gitlab.eaglesoftware.cn/
- 按提示输入注册令牌
Please enter the gitlab-ci token for this runner:
xxxxxxxxxxxxxxxxxxxx
- 按提示输入 Runner 描述信息,以后可从 CI/CD 设置页面修改
Please enter the gitlab-ci description for this runner:
[localhost.localdomain]: vm-wuzhuangzhuang
- 按提示输入与 Runner 关联的标签,标签可以用于选择 Runner, 以后可从 CI/CD 设置页面修改
Please enter the gitlab-ci tags for this runner (comma separated):
vm-wzz,centos
- 按提示输入 Runner Executors
Please enter the executor: docker+machine, docker-ssh+machine, kubernetes, virtualbox, docker, docker-ssh, parallels, shell, ssh, custom:
shell
- 如果选择 Docker 作为 executor, 还需要输入默认镜像,在 .gitlab-ci.yml 中未定义镜像时使用。
示例
官方文档有各种各样的示例。这里以 vue-element-admin 这个项目的配置演进为例,说明配置 CI/CD 过程中遇到的问题、想要达成的目标,以及解决办法。
项目说明
CI/CD 流水线一般由提交代码触发,包括自动编译(打包)、自动化测试、自动部署等步骤 (stages)。
要配置 CI/CD 流水线,首先需要知道手工如何实现这些工作,然后再编写代码实现自动化。
vue-element-admin 这个项目是基于 npm 的前端演示项目,没有后端和数据库等组件,项目组提供了一台 CentOS 虚拟机用于打包和部署,但没有提供自动化测试相关过程,所以只需在同一台机器上做打包和部署两个过程。
Version 1: Shell 版
Step1: Runner 安装配置
见前面的描述。
Step2: 打包工具安装
虽然这个项目有比较详尽的 README.md, 但仍没说明不支持最新的 node 12.16.1, 也没有说明需要安装 Development Tools. (实际上 .travis.yml 中有一行 node_js: 10)
如果对一个历史比较悠久的项目做一点小改动,这可能是一个需要时间修补的小坑。
# 去除以前安装的 nodejs
sudo yum remove nodejs
# 清除以前的安装源
sudo yum clean all
# 按官方文档 https://github.com/nodesource/distributions/blob/master/README.md#debinstall 设置安装源
curl -sL https://rpm.nodesource.com/setup_10.x | sudo bash -
# 安装 nodejs
sudo yum install -y nodejs
# 安装开发工具
yum install gcc-c++ make
# 或
# yum groupinstall 'Development Tools'
# 查看版本信息
npm version
查看版本信息的结果:
{ npm: '6.13.4',
ares: '1.15.0',
brotli: '1.0.7',
cldr: '35.1',
http_parser: '2.9.3',
icu: '64.2',
modules: '64',
napi: '5',
nghttp2: '1.39.2',
node: '10.19.0',
openssl: '1.1.1d',
tz: '2019c',
unicode: '12.1',
uv: '1.28.0',
v8: '6.8.275.32-node.55',
zlib: '1.2.11' }
Step3: 配置权限
因为后面想直接用 gitlab-runner 用户操作 docker 服务,故将 gitlab-runner 加入 docker 组中。
sudo usermod -aG docker gitlab-runner
sudo -u gitlab-runner -H docker info
Step4: 编写 .gitlab-ci.yml 文件
.gitlab-ci.yml
配置流水线如何运行,其编写详见 GitLab CI/CD Pipeline Configuration Reference.
v1.1 - 初始版本
第 1 版设置 2 个步骤,打包和部署, .gitlab-ci.yml
文件的内容如下。
stages:
- build
- deploy
# 所有 stage 之前的操作
before_script:
- pwd
- npm set registry https://mirrors.huaweicloud.com/repository/npm/
cache:
paths:
- node_modules/
- dist
build_job:
stage: build
tags:
- centos
- vm-wzz
script:
- echo '打包'
- npm install
- rm -rf ./dist
- npm run build
deploy_job:
stage: deploy
tags:
- centos
- vm-wzz
script:
- echo '部署'
- cd docker-compose
- docker-compose stop
- docker-compose up -d
在项目组提供的虚拟机上, 总耗时 03:06, 其中 build_job 耗时 02:03, deploy_job 耗时 01:02, deploy_job 耗时超出预期。
经检查,deploy_job 这一步要从 GitLab 上重新拉取代码,前一步 build_job 生成的 node_modules/ 和 dist/ 会被删除,然后从缓存区复制过来,虽然是本地缓存,但 node_modules/ 占用空间多达几百兆,而且不是两个步骤公用的,没有必要进行缓存。
116 ./public
1184 ./.git
44 ./plop-templates
9324 ./dist
8 ./build
12 ./docker-compose
84 ./mock
450948 ./node_modules
2868 ./src
40 ./tests
465488 .
v1.2 - 合并打包和部署
合并两个阶段后,总耗时 02:32.
修改后的 .gitlab-ci.yml
文件内容如下。
stages:
- build
# 所有 stage 之前的操作
before_script:
- pwd
- npm set registry https://mirrors.huaweicloud.com/repository/npm/
cache:
paths:
- node_modules/
- dist
build_job:
stage: build
tags:
- shell
- vm-wzz
script:
- echo '打包+部署'
- npm install
- npm run build
- cd docker-compose
- docker-compose stop
- docker-compose up -d
在 package.json
没有变化时,npm install
没有必要每次运行。
v1.3 - npm install 仅在需要时运行
在前面的基础上,继续修改 .gitlab-ci.yml
文件,只在 package.json
文件发生变化时执行 npm install
.
新提交版本触发的流水线最快总耗时 01:23。
stages:
- npm_install
- build
# 所有 stage 之前的操作
before_script:
- pwd
- npm set registry https://mirrors.huaweicloud.com/repository/npm/
cache:
paths:
- node_modules/
npm_install_job:
stage: npm_install
tags:
- shell
- vm-wzz
script:
- npm install
only:
changes:
- package.json
build_job:
stage: build
tags:
- shell
- vm-wzz
script:
- npm run build
- cd docker-compose
- docker-compose stop
- docker-compose up -d
按照同样的方法,也可以在 docker-compose/ 文件夹下面的文件发生变化时,重新构建 Docker 镜像。
曾经踩过的坑(修复的问题)
网络问题还是 Git 版本问题?
使用项目组提供的虚拟机,曾经有多次出现拉取代码出错的问题,而在华为云的云主机上注册的 Runner 从未出现过类似问题,当时怀疑是公司网络不稳定。
出现过的错误有:
- The remote end hung up unexpectedly
重新初始化现存的 Git 版本库于 /home/gitlab-runner/builds/z5U7Uaf7/0/opd/vue-element-admin/.git/
error: RPC failed; result=6, HTTP code = 0
fatal: The remote end hung up unexpectedly
ERROR: Job failed: exit status 1
- Could not resolve host: gitlab.eaglesoftware.cn
Fetching changes with git depth set to 50...
00:01
重新初始化现存的 Git 版本库于 /home/gitlab-runner/builds/z5U7Uaf7/0/opd/vue-element-admin/.git/
fatal: unable to access 'https://gitlab-ci-token:[MASKED]@gitlab.eaglesoftware.cn/opd/vue-element-admin.git/': Could not resolve host: gitlab.eaglesoftware.cn; Unknown error
ERROR: Job failed: exit status 1
- Could not resolve host: github.com (npm install 过程中出现的问题)
npm ERR! Error while executing:
npm ERR! /usr/bin/git ls-remote -h -t https://github.com/nhn/raphael.git
npm ERR!
npm ERR! fatal: unable to access 'https://github.com/nhn/raphael.git/': Could not resolve host: github.com; Unknown error
npm ERR!
npm ERR! exited with error code: 128
npm ERR! A complete log of this run can be found in:
npm ERR! /home/gitlab-runner/.npm/_logs/2020-03-09T07_25_38_871Z-debug.log
ERROR: Job failed: exit status 1
- git fetch-pack: expected shallow list
Running on localhost.localdomain...
00:00
Fetching changes with git depth set to 50...
00:03
重新初始化现存的 Git 版本库于 /home/gitlab-runner/builds/z5U7Uaf7/0/opd/vue-element-admin/.git/
fatal: git fetch-pack: expected shallow list
fatal: The remote end hung up unexpectedly
ERROR: Job failed: exit status 1
前 3 个可能真是网络不稳定,但第 4 个多次重试仍然不行,经百度搜索,确认是 CentOS 7 在安装 Runner 时默认安装的 Git 版本过低 (git version 1.8.3.1), 升级 Git 版本 (git version 2.22.2) 后恢复正常。由此可见,即使是个虚拟机,最好也安装个靠谱的版本。
CentOS 7 下的升级过程在 Git 官网有链接,这里使用 ius.io 提供的安装源:
yum install \
https://repo.ius.io/ius-release-el7.rpm \
https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
yum repolist
yum remove git
yum provides git
yum install git222
git --version
# 删除 git 时同时删除了依赖 git 的 gitlab-runner, 所以重新安装
yum install gitlab-runner
node 版本
node 之类的工具版本更新比较快,而且新版本不一定支持原先的代码。辛辛苦苦安装好 node 12.16.1, 还要想办法清除。详见前面描述。
如果使用 Docker, 这个坑修复的成本会低很多。
Docker Engine 未启动
$ docker-compose stop
Couldn't connect to Docker daemon at http+docker://localhost - is it running?
If it's at a non-standard location, specify the URL with the DOCKER_HOST environment variable.
ERROR: Job failed: exit status 1
这个问题比较明显,启动 Docker Engine 并设置开机启动后恢复正常。
systemctl start docker
systemctl enable docker
Version 2: Docker 版
Why
前面的版本虽然完成了打包和部署,但坑比较多,而且打包和部署是在同一台机器上,而测试环境、正式运行环境一般都是与开发环境分离的。
在这个版本中,我们使用 docker 完成打包,并使用 ssh 把打包好的软件部署到运行环境中。
这种部署方式需要运行 runner 的机器要能通过网络访问部署目标机器,比如从公司内网可以部署到云服务器,但反过来就不太方便;如果目标机器的 IP 地址是动态获取的,也容易出现问题。
Step1: Runner 安装配置
见前面的描述,以下略有不同:
Step2: 生成密钥对并分别配置到目标机器和 GitLab 环境变量
生成密钥对,不设置 passphrase, 然后将公钥配置到目标机器。
$ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/c/Users/96129/.ssh/id_rsa): id_rsa_ci_test
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in id_rsa_ci_test.
Your public key has been saved in id_rsa_ci_test.pub.
$ ssh-copy-id -i id_rsa_ci_test.pub root@10.44.111.27
$ cat id_rsa_ci_test
在 GitLab 项目设置 » CI/CD 页面,新增 3 个变量:
- SERVER_HOST: 目标机器的 IP 地址, 如前面的 10.44.111.27
- SERVER_USER: 目标机器的用户 login, 如前面的 root
- STAGING_PRIVATE_KEY: 私钥的全部内容,如前面 cat id_rsa_ci_test 的输出结果
这 3 个变量会在接下来的 .gitlab-ci.yml 文件中用到。
Step3: 编写 .gitlab-ci.yml 文件
测试好的 .gitlab-ci.yml 文件如下。
image: node:10.19.0-buster
stages:
- npm_install
- build_docker
- deploy
variables:
TARGET_DIR: ~/vue-element-admin/
# 所有 stage 之前的操作
before_script:
- 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )'
- mkdir -p ~/.ssh
- eval $(ssh-agent -s)
- '[[ -f /.dockerenv ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config'
- ssh-add <(echo "$STAGING_PRIVATE_KEY")
- npm set registry https://mirrors.huaweicloud.com/repository/npm/
stage_npm_install:
stage: npm_install
tags:
- docker
- vm-wzz
cache:
paths:
- node_modules/
script:
- npm install
only:
changes:
- package.json
stage_build_docker:
stage: build_docker
tags:
- docker
- vm-wzz
script:
- ssh $SERVER_USER@$SERVER_HOST "mkdir -p $TARGET_DIR/docker-compose/"
- scp -r docker-compose/* $SERVER_USER@$SERVER_HOST:$TARGET_DIR/docker-compose/
- ssh $SERVER_USER@$SERVER_HOST "docker-compose -f $TARGET_DIR/docker-compose/docker-compose.yml build"
only:
changes:
- docker-compose/**/*
stage_deploy:
stage: deploy
artifacts:
paths:
- dist/
tags:
- docker
- vm-wzz
cache:
paths:
- node_modules/
policy: pull
script:
- npm run build
- ssh $SERVER_USER@$SERVER_HOST "mkdir -p $TARGET_DIR/dist/"
- scp -r dist/* $SERVER_USER@$SERVER_HOST:$TARGET_DIR/dist/
- ssh $SERVER_USER@$SERVER_HOST "mkdir -p $TARGET_DIR/docker-compose/"
- scp -r docker-compose/* $SERVER_USER@$SERVER_HOST:$TARGET_DIR/docker-compose/
- ssh $SERVER_USER@$SERVER_HOST "cd $TARGET_DIR/docker-compose/ && docker-compose stop && docker-compose up -d"
这里把整个流水线分成 3 步,第 1 步为 npm_install, 只在 package.json 发生变化时运行,生成的文件作为后续步骤的缓存。
第 2 步为 build_docker, 在 docker-compose/ 文件夹下的内容发生变化时运行,由于其中并没有 Dockerfile, 直接使用的 nginx 服务,这一步并没有实质作用。
第 3 步为 deploy, 拉取第 1 步生成的缓存目录 node_modules/, 进行打包,并将打包后的软件复制到目标机器,指示目标机器重新启动容器。
注意事项
由于第 3 步依赖第 1 步生成的缓存,而第 1 步只在 package.json 发生变化时才触发运行,在首次提交 .gitlab-ci.yml 而 package.json 未同时变化时,流水线只运行第 3 步会出现失败。
此时,应从 GitLab 项目的 CI / CD 页面单击“运行流水线”,手动触发完整流水线的运行,以后再提交代码时触发运行的流水线将不会因此问题失败。
结果分析
由于拉取 docker 镜像、复制文件等相比 Version 1 的方式都将带来额外的资源消耗,增加了向 GitLab 上传工件的环节,流水线最快总耗时为 02:55 (在 package.json 等不发生变化时), 比 Version 1 的最佳结果约慢 90 秒钟。
但这种部署方式的几乎把所有步骤都写入代码中,非常清楚,而性能的下降可以通过更好的硬件设施来弥补。
更好的部署方式是把打包好的工件(如生成容器镜像)推送到统一的注册中心,在运行环境中拉取工件运行。这样,只有注册中心需要有固定的域名或 IP 地址,但这对资源要求较高,暂不考虑这种方式。
Docker 创建 Nginx 和 php-fpm环境
Docker创建Nginx和php-fpm环境
docker image pull nginx
docker image pull php:fpm
docker container run -d -it --name nginx -p 80:80 nginx
docker container run -d -it --name php-fpm -v /www:/www --network=container:nginx php:fpm
docker container run -d -it --name php-fpm -v /home/develop/service:/www --network=container:nginx php:fpm
docker container run -d \
--name php-fpm \
-v /data/server/pm/pm_service:/www \
-v /data/server/pm/logs:/logs \
-p 9000:9000 \
php:7.4.21-fpm
cd /usr/local/bin
./docker-php-ext-install mysqli
echo '
server {
listen 80;
server_name localhost;
location / {
root /www;
index index.html index.htm index.php;
}
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /service/www/$fastcgi_script_name;
include fastcgi_params;
}
}
' > default.conf
docker cp default.conf nginx:/etc/nginx/conf.d/default.conf
docker exec nginx nginx -s reload
mkdir /www
echo '<?php echo time();' > /www/test.php
curl http://127.0.0.1/test.php
Docker 安装 MongoDB
Docker 安装 MongoDB
MongoDB 是一个免费的开源跨平台面向文档的 NoSQL 数据库程序。
1、查看可用的 MongoDB 版本
访问 MongoDB 镜像库地址: mongo。
可以通过 Sort by 查看其他版本的 MongoDB,默认是最新版本 mongo:latest。
你也可以在下拉列表中找到其他你想要的版本:
此外,我们还可以用 docker search mongo 命令来查看可用版本:
docker image search mongo
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
mongo MongoDB document databases ... 1989 [OK]
mongo-express Web-based MongoDB admin int... 22 [OK]
mvertes/alpine-mongo light MongoDB container 19 [OK]
mongooseim/mongooseim-docker MongooseIM server the lates... 9 [OK]
torusware/speedus-mongo Always updated official Mon... 9 [OK]
jacksoncage/mongo Instant MongoDB sharded cluster 6 [OK]
mongoclient/mongoclient Official docker image for M... 4 [OK]
jadsonlourenco/mongo-rocks Percona Mongodb with Rocksd... 4 [OK]
asteris/apache-php-mongo Apache2.4 + PHP + Mongo + m... 2 [OK]
19hz/mongo-container Mongodb replicaset for coreos 1 [OK]
nitra/mongo Mongo3 centos7 1 [OK]
ackee/mongo MongoDB with fixed Bluemix p... 1 [OK]
kobotoolbox/mongo https://github.com/kobotoolb... 1 [OK]
valtlfelipe/mongo Docker Image based on the la... 1 [OK]
2、取最新版的 MongoDB 镜像
这里我们拉取官方的最新版本的镜像:
docker pull mongo:latest
3、查看本地镜像
使用以下命令来查看是否已安装了 mongo:
docker image ls
在上图中可以看到我们已经安装了最新版本(latest)的 mongo 镜像。
4、运行容器
安装完成后,我们可以使用以下命令来运行 mongo 容器:
docker run -itd --name mongo -p 27017:27017 mongo --auth
docker run -d \
--name mongo \
--restart=always \
-p 27017:27017 \
-v /mongo/initdb:/docker-entrypoint-initdb.d \
-v /mongo/datadic:/data/db \
-v /mongo/configdb:/data/configdb \
-e MONGO_INITDB_ROOT_USERNAME=mongoadmin \
-e MONGO_INITDB_ROOT_PASSWORD=123456 \
-e MONGO_INITDB_DATABASE=test \
mongo:4.4.8 --auth
db.createUser({ user:'mongoadmin',pwd:'123456',roles:[ { role:'userAdminAnyDatabase', db: 'admin'},"readWriteAnyDatabase"]});
db.auth('mongoadmin', '123456')
mongorestore -h 10.44.111.123:27017 -u mongoadmin -p 123456 --authenticationDatabase admin -d v3 ./
参数说明:
- -p 27017:27017 :映射容器服务的 27017 端口到宿主机的 27017 端口。外部可以直接通过 宿主机 ip:27017 访问到 mongo 的服务。
- --auth:需要密码才能访问容器服务。
5、安装成功
最后我们可以通过 docker container ps
命令查看容器的运行信息:
接着使用以下命令添加用户和设置密码,并且尝试连接。
docker container exec -it mongo mongo admin
# 创建一个名为 admin,密码为 123456 的用户。
> db.createUser({ user:'admin',pwd:'123456',roles:[ { role:'userAdminAnyDatabase', db: 'admin'},"readWriteAnyDatabase"]});
# 尝试使用上面创建的用户信息进行连接。
> db.auth('admin', '123456')
Docker 安装 PHP
Docker 安装 PHP
安装 PHP 镜像
方法一、docker pull php
查找 Docker Hub 上的 php 镜像:
可以通过 Sort by 查看其他版本的 php,默认是最新版本 php:latest。
此外,我们还可以用 docker search php 命令来查看可用版本:
docker search php
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
php While designed for web development, the PH... 1232 [OK]
richarvey/nginx-php-fpm Container running Nginx + PHP-FPM capable ... 207 [OK]
phpmyadmin/phpmyadmin A web interface for MySQL and MariaDB. 123 [OK]
eboraas/apache-php PHP5 on Apache (with SSL support), built o... 69 [OK]
php-zendserver Zend Server - the integrated PHP applicati... 69 [OK]
million12/nginx-php Nginx + PHP-FPM 5.5, 5.6, 7.0 (NG), CentOS... 67 [OK]
webdevops/php-nginx Nginx with PHP-FPM 39 [OK]
webdevops/php-apache Apache with PHP-FPM (based on webdevops/php) 14 [OK]
phpunit/phpunit PHPUnit is a programmer-oriented testing f... 14 [OK]
tetraweb/php PHP 5.3, 5.4, 5.5, 5.6, 7.0 for CI and run... 12 [OK]
webdevops/php PHP (FPM and CLI) service container 10 [OK]
这里我们拉取官方的镜像,标签为5.6-fpm
docker pull php:5.6-fpm
等待下载完成后,我们就可以在本地镜像列表里查到REPOSITORY为php,标签为5.6-fpm的镜像。
docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
php 5.6-fpm 025041cd3aa5 6 days ago 456.3 MB
Nginx + PHP 部署 Nginx 部署可以查看:Docker 安装 Nginx,一些 Nginx 的配置参考这篇文章。
启动 PHP:
docker run --name myphp-fpm -v ~/nginx/www:/www -d php:5.6-fpm
命令说明:
-
--name myphp-fpm : 将容器命名为 myphp-fpm。
-
-v ~/nginx/www:/www : 将主机中项目的目录 www 挂载到容器的 /www
创建 ~/nginx/conf/conf.d
目录:
mkdir ~/nginx/conf/conf.d
在该目录下添加 ~/nginx/conf/conf.d/test-php.conf
文件,内容如下:
server {
listen 80;
server_name localhost;
location / {
root /usr/share/nginx/html;
index index.html index.htm index.php;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
location ~ \.php$ {
fastcgi_pass php:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /www/$fastcgi_script_name;
include fastcgi_params;
}
}
配置文件说明:
- php:9000: 表示 php-fpm 服务的 URL,下面我们会具体说明。
- /www/: 是 myphp-fpm 中 php 文件的存储路径,映射到本地的 ~/nginx/www 目录。
启动 nginx:
docker run --name php-nginx -p 8083:80 -d \
-v ~/nginx/www:/usr/share/nginx/html:ro \
-v ~/nginx/conf/conf.d:/etc/nginx/conf.d:ro \
--link myphp-fpm:php \
nginx
- -p 8083:80: 端口映射,把 nginx 中的 80 映射到本地的 8083 端口。
- ~/nginx/www: 是本地 html 文件的存储目录,/usr/share/nginx/html 是容器内 html 文件的存储目录。
- ~/nginx/conf/conf.d: 是本地 nginx 配置文件的存储目录,/etc/nginx/conf.d 是容器内 nginx 配置文件的存储目录。
- --link myphp-fpm:php: 把 myphp-fpm 的网络并入 nginx,并通过修改 nginx 的 /etc/hosts,把域名 php 映射成 127.0.0.1,让 nginx 通过 php:9000 访问 php-fpm。
接下来我们在 ~/nginx/www 目录下创建 index.php,代码如下:
<?php
echo phpinfo();
?>
浏览器打开 http://127.0.0.1:8083/index.php
,显示如下: