.NET Core 容器化 @Docker
.NET Core 容器化之多容器应用部署 @Docker-Compose
.NET Core+MySql+Nginx 容器化部署
GitHub-Demo:Docker.NetCore.MySql
上两节我们通过简单的 demo 学习了 docker 的基本操作。这一节我们来一个进阶学习,完成 ASP.NET Core + MySql + Nginx 的容器化部署。
本文是基于 CentOS 7.4 环境进行演示,示例项目可以访问 Docker.NetCore.MySql 进行下载。同样我们还是以循序渐进的方式来展开。首先来基于 Docker 来试玩一下 MySQL。
- //拉取mysql镜像
- docker pull mysql
- $ docker images$
- REPOSITORY TAG IMAGE ID CREATED SIZE
- docker.io/mysql latest 7d83a47ab2d2 13 days ago 408.2 MB
- //创建一个mysql实例
- $ docker run --name hello.mysql -e MYSQL_ROOT_PASSWORD=123456 -d mysql
- $ docker ps
- CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
- e21bbd84e0b5 mysql "docker-entrypoint.sh" 3 minutes ago Up 3 minutes 3306/tcp hello.mysql
下面我们直接在容器中连接到我们刚刚创建的 mysql 数据库:
- $ docker exec -it hello.mysql \
- > mysql -uroot -p123456
- mysql: [Warning] Using a password on the command line interface can be insecure.
- Welcome to the MySQL monitor. Commands end with ; or \g.
- Your MySQL connection id is 8
- Server version: 5.7.20 MySQL Community Server (GPL)
- Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
- 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 实例其数据都在容器内部存储,这样就暴露了一个问题,如果容器销毁,那么对应的数据库数据就会丢失。那如何持久化存储容器内数据呢?我们可以通过挂载数据卷的方式来解决这一问题。
- //创建数据卷
- $ docker volume create --name hello.db
- hello.db
- //查看数据卷信息
- $ docker volume inspect hello.db
- [
- {
- "Name": "hello.db",
- "Driver": "local",
- "Mountpoint": "/var/lib/docker/volumes/hello.db/_data",
- "Labels": {},
- "Scope": "local"
- }
- ]
- // 挂载数据卷启动MySql实例
- $ docker run --name hello.mysql \
- > -v hello.db:/var/lib/mysql \
- > -e MYSQL_ROOT_PASSWORD=123456 -d mysql
上面是使用使用了
命令创建了一个数据卷,当然我们也可以自行挂载某个目录作为数据卷。
- docker volume create
为了演示方便,我准备了一个 ASP.NET Core+EFCore+MySql 的示例项目。其结构如下所示:
是基于. NET Core Mvc 模板项目,其中定义了一个 Product 实体,并通过 ProductsController 暴露 WebApi 接口。核心代码如下:
Product 实体类:
- public class Product
- {
- public int ProductId { get; set; }
- public string Name { get; set; }
- public decimal Price { get; set; }
- public int StockQty { get; set; }
- }
DbContext 类:
- public class MySqlDbContext : DbContext
- {
- public MySqlDbContext (DbContextOptions<MySqlDbContext> options)
- : base(options)
- {
- }
- public DbSet<Product> Products { get; set; }
- }
数据库初始化类:
- public class DbInitializer
- {
- public static void Initialize(MySqlDbContext context)
- {
- context.Database.EnsureCreated();
- if (context.Products.Any())
- {
- return;
- }
- var products = new Product[]
- {
- new Product{Name="iphone 6",Price=5000,StockQty=10 },
- new Product{Name="iphone 7",Price=6000,StockQty=10 },
- new Product{Name="iphone 7 plus",Price=7000,StockQty=10 },
- new Product{Name="iphone x",Price=8000,StockQty=10 }
- };
- context.Products.AddRange(products);
- context.SaveChanges();
- }
- }
该数据库初始化类会在项目启动时运行。详细代码可参考 Docker.NetCore.MySql 。
- $ yum install git
- $ git --version
- git version 1.8.3.1
- $ cd ~/demo
- $ git clone https://github.com/yanshengjie/Docker.NetCore.MySql.git
- Cloning into 'Docker.NetCore.MySql'...
- remote: Counting objects: 155, done.
- remote: Compressing objects: 100% (125/125), done.
- remote: Total 155 (delta 42), reused 123 (delta 25), pack-reused 0
- Receiving objects: 100% (155/155), 534.30 KiB | 333.00 KiB/s, done.
- Resolving deltas: 100% (42/42), done.
细心的你会发现,项目中已经定义了 Dockerfile,所以我们可以直接使用 docker build 构建镜像。
- # cd Docker.NetCore.MySql
- [root@iZ288a3qazlZ Docker.NetCore.MySql]# ls
- appsettings.Development.json docker-compose.yml Program.cs Views
- appsettings.json Dockerfile proxy.conf wwwroot
- bundleconfig.json Docker.NetCore.MySql.csproj README.md
- Controllers LICENSE ScaffoldingReadMe.txt
- Data Models Startup.cs
- //构建镜像
- # docker build -t docker.netcore.mysql .
- Sending build context to Docker daemon 3.045 MB
- Step 1 : FROM microsoft/dotnet:latest
- ---> 7d4dc5c258eb
- Step 2 : WORKDIR /app
- ---> Using cache
- ---> 98d48a4e278c
- Step 3 : COPY . /app
- ---> 6b1bf8bb5261
- Removing intermediate container b86460477977
- Step 4 : RUN dotnet restore
- ---> Running in 4e0a46f762bb
- Restoring packages for /app/Docker.NetCore.MySql.csproj...
- Installing Microsoft.CodeAnalysis.Razor 2.0.0.
- .....
- Restore completed in 216.83 ms for /app/Docker.NetCore.MySql.csproj.
- ---> 4df70c77916e
- Removing intermediate container 4e0a46f762bb
- Step 5 : EXPOSE 5000
- ---> Running in 11b421b3bd3e
- ---> 3506253060fe
- Removing intermediate container 11b421b3bd3e
- Step 6 : ENV ASPNETCORE_URLS http://*:5000
- ---> Running in 201aabbab72c
- ---> 7f29963a8d96
- Removing intermediate container 201aabbab72c
- Step 7 : ENTRYPOINT dotnet run
- ---> Running in c79f73cba162
- ---> 9d1fb6ee46cb
- Removing intermediate container c79f73cba162
- Successfully built 9d1fb6ee46cb
- [root@iZ288a3qazlZ Docker.NetCore.MySql]# docker images docker.netcore.mysql
- REPOSITORY TAG IMAGE ID CREATED SIZE
- docker.netcore.mysql latest 9d1fb6ee46cb 13 seconds ago 1.756 GB
docker 提供了 --link 参数用于在容器之间建立连接。下面我们实例化创建的镜像
并命名容器名为 hello.netcore.mysql,并使用 --link 参数与我们文章开头建立的 hello.mysql 容器建立连接。
- docker.netcore.mysql
- # docker run --name hello.netcore.mysql --link hello.mysql:db -d -p 5000:5000
- docker.netcore.mysql
这里需要特别注意一下
,这个参数就是告诉 Docker 容器需要使用 hello.mysql 容器,并将其别名命名为 db,这样在 hello.netcore.mysql 这个容器中就可以使用 db 来作为提供 mysql 数据库服务的服务器。这也就是为什么我们. NET Core 项目中连接字符串设置为 server=db; 的原因。
- --link = hello.mysql: db
- "ConnectionStrings": { "MySql": "server=db;database=MySqlDbContext;uid=root;pwd=123456;" }
- //查看运行中容器列表
- # docker ps
- CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
- 5cbfd27ebe2a docker.netcore.mysql "dotnet run" 2 minutes ago Up 2 minutes 0.0.0.0:5000->5000/tcp hello.netcore.mysql
- 4dfa4159b669 mysql "docker-entrypoint.sh" About an hour ago Up About an hour 3306/tcp hello.mysql
- //访问api/products
- [root@iZ288a3qazlZ Docker.NetCore.MySql]# curl http://localhost:5000/api/products
- [{"productId":1,"name":"iphone 6","price":5000.0000000000000000000000000,"stockQty":10},{"productId":2,"name":"iphone 7","price":6000.0000000000000000000000000,"stockQty":10},{"productId":3,"name":"iphone 7 plus","price":7000.0000000000000000000000000,"stockQty":10},{"productId":4,"name":"iphone x","price":8000.000000000000000000000000,"stockQty":10}]
从上图可知,我们完成了. NET Core 与 MySql 的连接。
结合上一篇文章 .NET Core 容器化之多容器应用部署 @Docker-Compose ,我们来使用 docker-compose 完成 asp.net core + mysql + nginx 的多容器部署。
- version: '2'
- services:
- db:
- container_name: hello.db
- environment:
- MYSQL_ROOT_PASSWORD: 123456
- volumes:
- - ./mysql:/var/lib/mysql
- web:
- container_name: hello.web
- build: .
- depends_on:
- - db
- links:
- - db
- reverse-proxy:
- container_name: hello.proxy
- image: nginx
- depends_on:
- - web
- ports:
- - "9090:8080"
- volumes:
- - ./proxy.conf:/etc/nginx/conf.d/default.conf
其中定义了三个服务:
- server {
- listen 8080;
- location / {
- proxy_pass http: //web:5000;
- }
- }
在启动 Compose 之前,建议清空上面创建的容器。也可以使用
清除所有容器。
- docker rm $(docker ps - qa)
- //启动compose
- [root@iZ288a3qazlZ Docker.NetCore.MySql]# docker-compose up -d
- Creating network "dockernetcoremysql_default" with the default driver
- Building web
- Step 1 : FROM microsoft/dotnet:latest
- ---> 7d4dc5c258eb
- Step 2 : WORKDIR /app
- ---> Using cache
- ---> 98d48a4e278c
- Step 3 : COPY . /app
- ---> d41b32323c0f
- Removing intermediate container 1259f5fb82bc
- Step 4 : RUN dotnet restore
- ---> Running in d482e355de77
- Restoring packages for /app/Docker.NetCore.MySql.csproj...
- Installing Microsoft.CodeAnalysis.Razor 2.0.0.
- .....
- Restore completed in 216.83 ms for /app/Docker.NetCore.MySql.csproj.
- ---> a0658008f161
- Removing intermediate container d482e355de77
- Step 5 : EXPOSE 5000
- ---> Running in dc6eeb29fd5e
- ---> a419314ece08
- Removing intermediate container dc6eeb29fd5e
- Step 6 : ENV ASPNETCORE_URLS http://*:5000
- ---> Running in c1d1474b14a0
- ---> 9cc13c549042
- Removing intermediate container c1d1474b14a0
- Step 7 : ENTRYPOINT dotnet run
- ---> Running in efdf0e857a84
- ---> 830ac11428cf
- Removing intermediate container efdf0e857a84
- Successfully built 830ac11428cf
- Creating hello.db ... done
- Creating hello.web ... done
- Creating hello.proxy ... done
- Creating hello.web ...
- Creating hello.proxy ...
- [root@iZ288a3qazlZ Docker.NetCore.MySql]# docker ps
- CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
- 6253bf85682e nginx "nginx -g 'daemon off" 33 seconds ago Up 28 seconds 80/tcp, 0.0.0.0:9090->8080/tcp hello.proxy
- ea553a9e22f2 dockernetcoremysql_web "dotnet run" 37 seconds ago Up 32 seconds 5000/tcp hello.web
- a1f5aa981bfb mysql "docker-entrypoint.sh" 38 seconds ago Up 36 seconds 3306/tcp hello.db
- [root@iZ288a3qazlZ Docker.NetCore.MySql]# docker-compose ps
- Name Command State Ports
- ----------------------------------------------------------------------------------
- hello.db docker-entrypoint.sh mysqld Up 3306/tcp
- hello.proxy nginx -g daemon off; Up 80/tcp, 0.0.0.0:9090->8080/tcp
- hello.web dotnet run Up 5000/tcp
- [root@iZ288a3qazlZ Docker.NetCore.MySql]# curl http://localhost:9090/api/products
- [{"productId":1,"name":"iphone 6","price":5000.0000000000000000000000000,"stockQty":10},{"productId":2,"name":"iphone 7","price":6000.0000000000000000000000000,"stockQty":10},{"productId":3,"name":"iphone 7 plus","price":7000.0000000000000000000000000,"stockQty":10},{"productId":4,"name":"iphone x","price":8000.000000000000000000000000,"stockQty":10}]
上面的运行结果显示,我们已经成功完成了 ASP.NET Core+MySql+Nginx 的多容器应用部署。通过浏览器访问
即可访问我们暴露的 api。
- http: <ipaddress > :9090 / api / products
我们来验证一下数据库是否成功创建:
- [root@iZ288a3qazlZ Docker.NetCore.MySql]# ls mysql
- auto.cnf client-key.pem ib_logfile0 performance_schema server-key.pem
- ca-key.pem MySqlDbContext ib_logfile1 private_key.pem sys
- ca.pem ib_buffer_pool ibtmp1 public_key.pem
- client-cert.pem ibdata1 mysql server-cert.pem
- [root@iZ288a3qazlZ Docker.NetCore.MySql]# docker exec -it hello.db mysql -uroot -p123456
- mysql: [Warning] Using a password on the command line interface can be insecure.
- Welcome to the MySQL monitor. Commands end with ; or \g.
- Your MySQL connection id is 8
- Server version: 5.7.20 MySQL Community Server (GPL)
- Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
- 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 |
- | MySqlDbContext |
- | mysql |
- | performance_schema |
- | sys |
- +-----------------------+
- 5 rows in set (0.00 sec)
- mysql> use MySqlDbContext;
- Reading table information for completion of table and column names
- You can turn off this feature to get a quicker startup with -A
- Database changed
- mysql> show tables;
- +---------------------------------+
- | Tables_in_MySqlDbContext |
- +---------------------------------+
- | Products |
- +---------------------------------+
- 1 row in set (0.00 sec)
- mysql> select * from Products;
- +-----------+---------------+-------------------------------------+----------+
- | ProductId | Name | Price | StockQty |
- +-----------+---------------+-------------------------------------+----------+
- | 1 | iphone 6 | 5000.000000000000000000000000000000 | 10 |
- | 2 | iphone 7 | 6000.000000000000000000000000000000 | 10 |
- | 3 | iphone 7 plus | 7000.000000000000000000000000000000 | 10 |
- | 4 | iphone x | 8000.000000000000000000000000000000 | 10 |
- +-----------+---------------+-------------------------------------+----------+
- 4 rows in set (0.00 sec)
从上面的运行结果可知,我们成功将项目文件夹下的 mysql 文件夹挂载到容器内部进行数据持久化。
本文通过先介绍如何基于 Docker 实例化 MySQL 容器,再介绍如何通过挂载数据卷来持久化 MySQL 数据,以及如何使用 --Link 参数进行容器之间的连接,完成了. NET Core 连接 MySQL 数据库。
最后,使用 Docker-Compose 综合 ASP.NET Core+MySQL+Nginx 完成了容器化部署。
下一节我们来介绍下如何使用 Docker-Swarm 进行集群部署。
来源: https://www.cnblogs.com/sheng-jie/p/8249660.html