k8s dotnet core部署
但是还有个问题,如果我们的配置文件变动了怎么办呢,比如数据库连接,redis地址,这个是不是意味着我们需要重新构建镜像,重新部署到k8s呢?EXPOSE:容器运行后,访问程序暴露的接口,这个很重用,后面再部署k8s时会用到,注意,这个是每个pod的端口,如果我们有多套程序,这个端口是可以用一个的,不会和其他pod有冲突。上面我们看到,第一次部署的时候,我们的IP是86,但是重启以后,IP变成了90
上一节,.net core k8s 微服务系列-(3)k8s coredns和dashboard部署我们已经搭建好了k8s的环境,今天,我们部署一下.net core 到k8s。
我们部署.net core的流程一般是编写代码,构建镜像,部署到k8s。
这里,因为没有那么多资源,所以准备用单机的k8s部署。执行下面的命令,就可以再master上部署Pod。生产环境上面,严禁这样部署,还是需要使用集群。
kubectl taint nodes --all node-role.kubernetes.io/master-
构建docker镜像,我们需要使用的dockerfile。这个文件类似于我们需要执行一系列cmd命令的时候,一般会创建一个bat文件,这样每次执行批处理就行。同样,dockerfile里面就是docker image构建的一批指令。
我们在创建项目的时候,选择启用docker,这样,项目创建的时候,就会自动的生成dockerfile文件。如果原来没有启用,也可以自己创建一个dockerfile的文件放在根目录下。
dockerfile里面的指令一般都是比较固定,没有特殊需求,一般不需要做改动。
FROM指令:设置后续构建依赖的基础镜像,.net core 需要用到asp.net core 3.1镜像,编译的时候,需要用到dotnet sdk 3.1;
WORKDIR:通过镜像创建容器后,这个程序会放到容器的哪个目录,类型于我们手动部署时,在电脑上新建文件夹,把程序放进去。这个命令会直接定位到文件夹下面,没有的时候,就会在容器里面创建目录。
EXPOSE:容器运行后,访问程序暴露的接口,这个很重用,后面再部署k8s时会用到,注意,这个是每个pod的端口,如果我们有多套程序,这个端口是可以用一个的,不会和其他pod有冲突。我们这里的pod只对应一个docker容器,虽然可以对应多个容器。
COPY:复制文件到WORKDIR指定的目录。
RUN:执行命令,类似于CMD。
ENTRYPOINT:容器启动后执行的命令,与RUN指令的区别是不可以被docker run覆盖 , 会把 docker run 后 面 的 参 数 当 作 传 递 给ENTRYPOINT 指令的参数。
FROM mcr.microsoft.com/dotnet/aspnet:3.1 AS base
WORKDIR /app #在容器里面里面创建app目录
EXPOSE 80 #程序运行的端口
FROM mcr.microsoft.com/dotnet/sdk:3.1 AS build
WORKDIR /src #创建src目录
COPY ["mozhi.smartinvent.demo.csproj", "."] #将程序从dockerfile的目录复制到src
RUN dotnet restore "./mozhi.smartinvent.demo.csproj" #还原程序的nuget包
COPY . .
WORKDIR "/src/."
RUN dotnet build "mozhi.smartinvent.demo.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "mozhi.smartinvent.demo.csproj" -c Release -o /app/publish /p:UseAppHost=false
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "mozhi.smartinvent.demo.dll"] #部署容器后运行程序
我们先将创建的项目代码上传的centos服务器。需要用到ftp的小伙伴,可以参考我的文章如何在centos 上搭建ftp服务器?这里会有详细的vsftp搭建的过程。
接着,我们执行构建镜像的命令
cd /root/Documents/mozhi/demo #切换到自己代码的目录
docker build -t mozhi/demo:v1.0.0 -f Dockerfile . --network host #注意,最后面的"."必须要
在restore nuget package的时候,会提示 api.nuget.org无法访问,我们可以更改一下hosts的文件,指定IP地址。这个地址可能在变,建议用IP/IPv6查询,服务器地址查询 - 站长工具自己查一下。
输入命令,查看我们的镜像是否已经成功生成。
docker images
镜像生成以后,我们把它上传到我们的docker 私有仓库,还没搭建docker repository的小伙伴,请参考这篇文章如何搭建自己的docker私有仓库。执行下面的命令:
docker login 192.168.41.147:5000 #登录docker私有仓库
docker tag mozhi/demo:v1.0.0 192.168.41.147:5000/demo:v1.0.0 #给镜像重新打标签
docker push 192.168.41.147:5000/demo:v1.0.0
好了,到这里,我们的.net core 镜像就已经完成了,接着就是把我们的镜像部署到k8s上面。
k8s部署,我们采用yaml文件方式。
在部署前,我们需要先创建命名空间和docker repository的凭证,用于从私有仓库拉取镜像。
kubectl create ns mozhi-smartinvent
kubectl create secret \
docker-registry dockersecret \
--docker-server=192.168.41.147:5000 \
--docker-username=admin \
--docker-password=123456 \
-n mozhi-smartinvent
接着,我们在服务器上新建一个deployment-demo.yaml的文件。
replicas:表示初始Pod数量
containers:pod里面容器的相关配置。
image指的是镜像拉取地址;
ports是dockerfile里面的Expose配置的端口;
env:一个环境参数配置,有兴趣的小伙伴,可以阅读一下我的文章多个开发部署环境,不想更改配置文件,怎么办?里面有相关的解读。
imagePullPolicy:镜像拉取失败的操作,Always标示一直拉取
imagePullSecrets:镜像拉取的一些凭证设置,这里,我们需要登录docker私有仓库
---
kind: Deployment
apiVersion: apps/v1
metadata:
name: mozhi-demo
namespace: mozhi-smartinvent
labels:
name: mozhi-demo
spec:
replicas: 1
selector:
matchLabels:
name: mozhi-demo
template:
metadata:
labels:
name: mozhi-demo
spec:
containers:
- name: mozhi-demo
image: 192.168.41.147:5000/demo:v1.0.0
ports:
- containerPort: 80
env:
- name: ASPNETCORE_ENVIRONMENT
value: Development
imagePullPolicy: Always
imagePullSecrets:
- name: dockersecret
这里面,如果我们更改配置,很有可能会通不过,报yaml语法错误。这里有几个网站可以验证你的yaml文件是否符合语法。
YAML、YML在线编辑器(格式化校验)-BeJSON.com 这个站点可以验证,还可以在json和yaml之间进行转换。我有时候写复杂的yaml,会先写json格式的,然后再转换成yaml,非常的好用。
切换到刚才的文件路径,执行命令:
kubectl apply -f deployment-demo.yaml -n mozhi-smartinvent #部署pod
kubectl get pods --all-namespaces -o wide #查看pod状态
可以看见,在mozhi-smartinvent下,创建了名为
mozhi-demo-85856564fb-kvmvr的pod,并且状态为Running,访问IP为10.224.219.86(这个IP是会变化的,每次重启都会不一样)。
我们再执行命令,是不是看到了熟悉的界面。平时我们用visul studio调试的时候,就会在CMD命令窗口出现程序执行的log信息。
kubectl get pods --show-labels -n mozhi-smartinvent
kubectl logs mozhi-demo-85856564fb-kvmvr -n mozhi-smartinvent
我们登录k8s的dashboard站点,同样可以看到上面的信息:
但是,我们直接用执行curl
http://10.224.219.90/WeatherForecast(这里我重启过服务,IP不在是86,变成90了),结果访问不了,难道我们程序没有部署成功?哈哈,有时候不要怀疑自己,因为我们还有其他东西没有配置。
上面我们看到,第一次部署的时候,我们的IP是86,但是重启以后,IP变成了90。因为Pod是可以增加,删除的嘛,可以想想,其实这个IP是完全没法暴露出去给其他程序调用的。这个其实和k8s的网络访问的策略有关系。
k8s要访问的话,其实是通过Service转发的,这个Service会自动去找一个Pod进行访问。它创建以后,IP在整个集群中,就不再变化。它会指定了Pod的外网地址和Pod之间通信的地址。
我们新建一个service-demo.yaml文件。这里的kind就变成了Service
type:常用有两种方式:ClusterIP , NodePort。
ClusterIP:表示集群内都是可以相互访问,但是外网无法访问,它对应的是port配置的端口,targetPort端口对应的就是dockerfile里面EXPOSE端口;
NodePort:可以暴露主机的一个端口给外网访问,它对应的是nodePort配置的端口,端口范围30000-32767,如果type为nodePort,但是Ports里面没有配置nodePort,k8s会自动分配一个。
selector:service关联的pod名称,表示这个service对应的是name为mozhi-demo的所有pod。
---
kind: Service
apiVersion: v1
metadata:
name: mozhi-demo
namespace: mozhi-smartinvent
spec:
type: NodePort
ports:
- port: 44321
targetPort: 80
nodePort: 30246
selector:
name: mozhi-demo
执行命令,创建service,打开dashboard,就可以查看service的详细信息。
kubectl apply -f service-demo.yaml -n mozhi-smartinvent
然后我们再重新执行
curl http://10.1.153.137:44321/WeatherForecast #集群IP
curl http://192.168.41.147:30246/WeatherForecast #外网IP
可以看到,我们用service的不同IP:Port ,成功访问到了Pod里面的.net core 程序。接下来,我们试一下k8s重要的功能,缩放。
我们在dashboard界面上将副本数量改成2。可以看到k8s自动帮我们创建了新的Pod。是不是很激动,我们只要动动手指,并不需要做什么,就完成了程序的分布式部署。完全不像原来部署IIS站点那样,需要上传文件,更改程序配置的IP端口。甚至k8s还可以检测Pod的资源使用率,自动伸缩pod数量。
好了,我们的.net core程序已经成功部署到了k8s,是不是非常的有成就感。但是还有个问题,如果我们的配置文件变动了怎么办呢,比如数据库连接,redis地址,这个是不是意味着我们需要重新构建镜像,重新部署到k8s呢?再我们代码没有做更新的情况下,当然不需要,k8s为了准备了ConfigMaps。专门用来更新Pod容器的配置信息,我将会在下一节详细来阐述,欢迎小伙伴们关注我,方便第一时间推送给你。
如果你觉得我的文章还不错,欢迎关注,转发和评论。大家也可以在微信公众号和今日头条搜索"墨汁软件"关注我哟!
更多推荐
所有评论(0)