深度优先

这个家伙好懒,除了文章什么都没留下

0%

【Docker】部署常用软件

Docker 安装

卸载旧版本

1
2
3
4
5
6
7
8
sudo yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine

安装依赖包

1
sudo yum install -y yum-utils device-mapper-persistent-data lvm2

添加 yum 软件源

鉴于国内网络问题,建议使用国内源,官方源请在注释中查看,执行下面的命令添加yum软件源:

1
2
3
4
5
6
7
8
9
sudo yum-config-manager \
--add-repo \
https://mirrors.ustc.edu.cn/docker-ce/linux/centos/docker-ce.repo


# 官方源
# $ sudo yum-config-manager \
# --add-repo \
# https://download.docker.com/linux/centos/docker-ce.repo

安装 Docker CE

更新yum软件源缓存,并安装docker-ce

1
2
sudo yum makecache fast
sudo yum install docker-ce

启动 Docker CE

1
2
sudo systemctl enable docker
sudo systemctl start docker

测试 Docker 是否安装正确

1
docker run hello-world

若能正常输出以下信息,则说明安装成功。

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
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
d1725b59e92d: Pull complete
Digest: sha256:0add3ace90ecb4adbf7777e9aacf18357296e799f81cabc9fde470971e499788
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 Hub拉取镜像有时会遇到困难,此时可以配置镜像加速器:

1
vi /etc/docker/daemon.json

添加镜像地址:

1
2
3
4
5
6
{
"registry-mirrors": [
"https://dockerhub.azk8s.cn",
"https://hub-mirror.c.163.com"
]
}

之后重新启动服务:

1
2
sudo systemctl daemon-reload
sudo systemctl restart docker

或者

1
2
3
4
5
6
7
8
9
10
11
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": [
"https://od404bh3.mirror.aliyuncs.com",
"https://dockerhub.azk8s.cn",
"https://hub-mirror.c.163.com"
]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker

执行 docker info,如果从结果中看到了如下内容,说明配置成功:

1
2
Registry Mirrors:
https://dockerhub.azk8s.cn/

测试镜像地址

国内无法直接获取 gcr.io/* 镜像:

1
docker pull gcr.azk8s.cn/google_containers/hyperkube-amd64:v1.9.2

若能拉取到则配置成功!

Nginx 代理服务器配置

创建挂载文件夹

1
2
3
4
cd /opt/
mkdir -p docker/nginx
cd docker/nginx/
mkdir {logs,conf,cert,website}

logs存放nginx相关日志,conf存放default.conf文件,
cert存放https证书,website存放静态网页文件

创建default.conf文件

1
vi conf/default.conf

编辑内容:

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
server {
listen 80;
server_name localhost;

#charset koi8-r;
#access_log /var/log/nginx/host.access.log main;

add_header Access-Control-Allow-Origin *;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html =404; #解决angular刷新404问题

if ($request_method = 'OPTIONS') {
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods GET,POST,PUT,DELETE,OPTIONS;
return 204;
}
}

location ^~ /api/signalR
{
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Cpnnection "upgrade";
proxy_pass http://192.168.0.101:443;
proxy_cache_bypass $http_upgrade;
}

location ^~ /api/ {
if ($request_method = 'OPTIONS') {
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods GET,POST,PUT,DELETE,OPTIONS;
return 204;
}
proxy_pass http://192.168.0.101:443;
}
#error_page 404 /404.html;

# redirect server error pages to the static page /50x.html
# error_page 500 502 503 504 /50x.html;
# location = /50x.html {
# root /usr/share/nginx/html;
# }

# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
# location ~ \.php$ {
# proxy_pass http://127.0.0.1;
# }

# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
# location ~ \.php$ {
# root html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
# }

# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}

创建nginx.conf文件

1
vi nginx.conf

编辑内容:

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
user  nginx;
worker_processes 1;

error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;

events {
worker_connections 1024;
}

http {
include /etc/nginx/mime.types;
default_type application/octet-stream;

log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';

access_log /var/log/nginx/access.log main;

server {
listen 80;
server_name localhost;

#charset koi8-r;
#access_log /var/log/nginx/host.access.log main;

add_header Access-Control-Allow-Origin *;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html =404;

if ($request_method = 'OPTIONS') {
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods GET,POST,PUT,DELETE,OPTIONS;
return 204;
}
}
}

# 配置http重定向到https
server {
listen 80;
server_name blog.bfsdfs.com;
rewrite ^(.*)$ https://$host$1 permanent;
}
# 配置https证书,和端口转发
server {
listen 443 ssl;
server_name www.test.com;
ssl_certificate cert/www.test.pem;
ssl_certificate_key cert/www.test.key;
ssl_session_timeout 5m;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
location / {
proxy_pass http://192.168.0.4:81/;
proxy_set_header Host $host;
proxy_set_header X-Real-Ip $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
}
}

sendfile on;
#tcp_nopush on;

keepalive_timeout 65;

#gzip on;

include /etc/nginx/conf.d/*.conf;
}

cert目录存放https证书

运行Nginx

1
2
3
4
5
6
7
docker run --name nginx -d -p 80:80 -p 443:443 --restart always \
-v /opt/docker/nginx/website:/usr/share/nginx/html \
-v /opt/docker/nginx/logs:/var/log/nginx \
-v /opt/docker/nginx/conf:/etc/nginx/conf.d \
-v /opt/docker/nginx/nginx.conf:/etc/nginx/nginx.conf \
-v /opt/docker/nginx/cert:/etc/nginx/cert \
nginx

查看运行情况

1
docker ps

MySql 安装与配置

创建MySql挂载目录

1
2
3
4
cd /opt/
mkdir -p docker/mysql
cd docker/mysql/
mkdir {conf,data,logs}

说明:conf存放配置文件,data存放数据文件,logs存放日志文件

安装MySql

1
2
3
4
5
docker run -p 8606:3306 --name mysql --restart always \
-v /opt/docker/mysql/conf:/etc/mysql/conf.d \
-v /opt/docker/mysql/logs:/var/log/mysql \
-v /opt/docker/mysql/data:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=123456 -d mysql:8.0

查看MySql运行情况

1
docker ps

允许远程连接

进入到mysql容器

1
docker exec -it mysql /bin/bash

登录mysql数据库

1
mysql -u root -p 123456

支持远程连接

1
2
ALTER user 'root'@'%' IDENTIFIED WITH mysql_native_password BY '123456';
FLUSH PRIVILEGES;

开放3306端口

1
2
3
firewall-cmd --zone=public --add-port=3306/tcp –permanent 
firewall-cmd --reload
firewall-cmd --zone=public --query-port=3306/tcp

数据库连接字符串

1
server=ipaddr,port=3306,username=root,password=123456

安装 .Net Core SDK

通过yum安装

1
2
3
sudo rpm -Uvh https://packages.microsoft.com/config/rhel/7/packages-microsoft-prod.rpm
sudo yum update
sudo yum install dotnet-sdk-2.1

通过下载文件安装

以.net core 3.1为例:

1
2
3
4
5
6
cd /opt/docker
mkdir {download,dotnet}
cd download
wget https://download.visualstudio.microsoft.com/download/pr/c4b503d6-2f41-4908-b634-270a0a1dcfca/c5a20e42868a48a2cd1ae27cf038044c/dotnet-sdk-3.1.101-linux-x64.tar.gz

tar zxf dotnet-sdk-3.1.101-linux-x64.tar.gz -C /opt/docker/dotnet

配置环境变量:

1
2
3
4
5
6
7
8
9
10
11
vi /etc/profile

# 在文件末尾添加
export DOTNET_ROOT=/opt/docker/dotnet
export PATH=$PATH:/opt/docker/dotnet

# 重新加载环境变量
source /etc/profile

# 查看net core信息
dotnet

部署 .Net Core WebApi

创建挂载目录

1
2
cd /opt/docker
mkdir webapi

创建Dockerfile文件

1
vi /opt/docker/webapi/Dockerfile

编辑内容:

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
FROM mcr.microsoft.com/dotnet/core/aspnet:2.2-stretch-slim AS base
WORKDIR /app
EXPOSE 80

ENV LANG C.UTF-8

# 设置代理
# ENV http_proxy http://your-proxy-server:port
# ENV https_proxy https://your-proxy-server:port
# ENV no_proxy 127.0.0.1,/var/run/docker.sock

# 开发环境
ENV ASPNETCORE_ENVIRONMENT "Development"
ENV ASPNETCORE_WEBWEBSITE "测试环境API"

# 正式环境
# ENV ASPNETCORE_ENVIRONMENT "Production"
# ENV ASPNETCORE_WEBWEBSITE "正式环境API"

# 替换源
RUN sed -i 's#http://deb.debian.org#https://mirrors.163.com#g' /etc/apt/sources.list
RUN apt-get clean

# 安装 libgdiplus
RUN apt-get update
RUN apt-get install -y libgdiplus
RUN cd /usr/lib
RUN ln -s libgdiplus.so gdiplus.dll

# 时区设置
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
RUN echo 'Asia/Shanghai' >/etc/timezone

ENTRYPOINT ["dotnet", "api.dll"]

build生成docker镜像

1
docker build -t api-images .

运行docker镜像

1
docker run -d --name api --restart always -v /opt/docker/api:/app -p 82:80 api-images

安装 SqlServer

下载SQL Server镜像

1
sudo docker pull microsoft/mssql-server-linux:2017-latest

启动SQL Server容器:

1
2
3
4
5
sudo docker run -e 'ACCEPT_EULA=Y' -e 'MSSQL_SA_PASSWORD=123456' \
-p 1433:1433 --name sql-server --restart always \
-d microsoft/mssql-server-linux:2017-latest

# 具体参数意义,请参看微软文档。(MSSQL_SA_PASSWORD为初始密码,可以自己修改)

修改 sa 密码

1
2
3
sudo docker exec -it sql-server /opt/mssql-tools/bin/sqlcmd \
-S localhost -U SA -P 'Asdfgh123' \
-Q 'ALTER LOGIN SA WITH PASSWORD="qazWSX123"'

连接数据库

1
sudo docker exec -it sql-server "bash"

简单操作

1
2
3
CREATE DATABASE TestDB
SELECT Name from sys.Databases
GO

外部访问SQL Server

安装 sqlcmd,前提已经安装了 nodejs(node 安装请自行搜索)
执行命令:

1
npm install -g sqlcmdjs

执行查询命令:

1
sqlcmd -s 127.0.0.1 -o 1433 -u SA -p "123456" "select name, database_id from sys.databases"

安装 Redis

创建挂载目录

创建宿主机 redis 容器的数据和配置文件目录

1
2
3
mkdir /opt/docker/redis/{conf,data} -p
cd /opt/docker/redis

获取Redis的默认配置模版

1
2
3
4
5
6
7
8
9
10
11
# 获取 redis 的默认配置模版
# 这里主要是想设置下 redis 的 log / password / appendonly
# redis 的 docker 运行参数提供了 --appendonly yes 但没 password
wget https://raw.githubusercontent.com/antirez/redis/4.0/redis.conf -O conf/redis.conf

# 直接替换编辑
sed -i 's/logfile ""/logfile "access.log"/' conf/redis.conf
sed -i 's/# requirepass foobared/requirepass 123456/' conf/redis.conf
sed -i 's/appendonly no/appendonly yes/' conf/redis.conf

# 这里可能还需配置一些 bind protected-mode

创建Redis容器

创建并运行一个名为 redis 的容器

1
2
3
4
5
6
7
8
docker run \
-p 6379:6379 \
-v $PWD/data:/data \
-v $PWD/conf/redis.conf:/etc/redis/redis.conf \
--privileged=true \
--name redis --restart always \
-d redis redis-server /etc/redis/redis.conf

进入到容器里面

1
docker exec -it redis bash redis-cli

配置外网可以访问

更改redis.conf文件

1
2
3
4
5
# 将这个注释掉
# bind 127.0.0.1

# no 改为 yes
protected-mode yes

集成 Gitlab Runner

创建挂载目录

1
2
mkdir -p /opt/docker/gitlab/config
mkdir -p /opt/docker/output

说明:output为gitlab-runner打包后输出文件的目录,可以让其他容器挂载这个目录

授权添加用户

1
2
3
4
chmod 777 /var/run/docker.sock

useradd gitlab-runner
usermod -aG docker gitlab-runner

创建gitlab-runner容器

1
2
3
4
5
6
7
8
docker run -d --name gitlab-runner --restart always \
-v /opt/docker/gitlab/config:/etc/gitlab-runner \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /usr/bin/docker:/usr/bin/docker \
-v /opt/docker/blog:/tmp/output/blog \
-v /opt/docker/webapi:/tmp/output/webapi \
-v /opt/docker/iot-client:/tmp/output/iot-client \
gitlab/gitlab-runner:latest

注册gitlab-runner

1
docker exec -it gitlab-runner gitlab-ci-multi-runner register

依次输入 gitlab地址,token,tag,描述,shell

进入容器

1
2
3
4
5
6
7
8
docker exec -it gitlab-runner /bin/bash

apt-get update
apt-get install rpm
apt-get install yum
apt-get install -y libltdl7

# 安装.net core sdk 可参考上面的

编辑 .gitlab-ci.yml

先以一个最简单的为例,如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
stages:
- deploy
deploy_job:
stage: deploy
script:
- cd /tmp/blog
- git pull
- cd demo
- source /etc/profile
- version=`date "+%Y.%m.%d.1"`
- dotnet build -c Release -p:Version=${version} -o /tmp/output
- docker stop blog-api
- rm -rf /tmp/blog-website/*
- cp -r /tmp/output /tmp/blog-website
- docker start blog-api

程序里获取版本信息:

1
2
3
4
5
6
7
8
9
10
11
var version = FileVersionInfo.GetVersionInfo(Assembly.GetEntryAssembly().Location).FileVersion;
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseSwagger();
app.UseSwaggerUI(option =>
{
option.SwaggerEndpoint("/swagger/v2/swagger.json", $"业务-接口文档 v{version}");
option.SwaggerEndpoint("/swagger/v1/swagger.json", $"基础-接口文档 v{version}");
});
}

安装Nodejs

1
2
3
4
5
6
7
8
9
10
wget http://nodejs.org/dist/v0.10.30/node-v0.10.30-linux-x64.tar.gz

tar --strip-components 1 -xzvf node-v* -C /usr/local

node --version

npm install -g n

n latest

docker 常用命令

查看容器信息

1
docker inspect

查看日志信息

1
docker logs -t --tail=10 <容器id>

容器自动启动设置

在运行时容器时设置,在run命令后加 –restart=always ,如:

1
docker run --restart=always -d --name api -v /opt/docker/api:/app -p 82:80 api-images

或,给已运行的容器添加自启动,命令:

1
docker update --restart=always <容器Id>

Vim 安装

1
2
apt-get update
apt-get install vim

开放端口

1
2
3
firewall-cmd --zone=public --add-port=80/tcp –permanent 
firewall-cmd –reload #重新载入
firewall-cmd --zone=public --query-port=80/tcp #查看

容器间通信

bridge方式:

1
2
3
4
docker network create --driver bridge mysql-network
docker network ls
docker inspect mysql-network
docker run -d --network mysql-network --name 容器名 镜像名

coverage report