一直在持续研究云原生领域的相关知识,虽然容器技术已经崛起很长时间了,但是没有机会在真实的项目中进行实战,所以总是学了忘,最终还是啥都没学会。
最近抽空在本地搭建了一个minikube的集群环境,顺便复习了一下docker,然后选用最熟悉的.net创建了Web API发布到minikube并运行。对于kubernetes和docker这里就不再做过多介绍,本文就算是记录一下对kubernetes和docker的再次入门吧。.
相关环境如下:
Ubuntu Server 22.04.1
minikube v1.27.1 on Ubuntu
docker 20.10.17 on Ubuntu
dotnet 6.0.402
首先创建一个.net core的Web API,并切换到项目目录后运行:
dotnet new webapi -o hello-minikube
cd xxxxxx
dotnet run
如下图:
dotnet new webapi默认创建了一个天气预报的API,访问一下控制台中输出的应用程序地址+API的Endpoint,结果如下:
由于本环境使用的是以docker为驱动的minikube,所以接下来开始使用Dockerfile对创建的API进行容器化。
对于该API有两种容器化操作方式:
在镜像内部编译并发布Web API,然后构建镜像
在镜像外部编译并发布Web API,然后构建镜像
对于这两种操作方式的不同,后面会再进行深入研究和阐述。在本文中,由于我的docker是在Ubuntu上安装的,所以使用在镜像外部编译发布之后,然后使用发布后的文件在Ubuntu上构建docker镜像。
发布Web API应用:
dotnew publish -c Release -o hello-minikube-pubish
在发布后的目录下创建Dockerfile:
code Dockerfile
使用该方式执行容器化操作,相对来讲Dockerfile比较简单,内容如下:
FROM mcr.microsoft.com/dotnet/aspnet:latest
COPY hello-minikube-publish/ App/
WORKDIR /App
ENTRYPOINT ["dotnet","hello-minikube.dll"]
拷贝发布后的文件到Ubuntu:
cp -r /mnt/hgfs/Host\ Edisk/hello-minikube-pubilsh/ ~/app/hello-minikube-publish
此处需要将Dockerfile移动到hello-minikube-publish的同级目录。
查看一下相关的文件:
开始构建docker镜像,并查看:
docker build -t hello-minikube-api .
docker images
可以看到有两个镜像,一个是拉取的aspnet的镜像,一个是本示例中构建的名称为hello-minikube-api的镜像。镜像构建完成之后,开始准备发布到minikube。
接下来准备minikube的部署,首先编写deployment的yaml文件,内容如下:
apiVersion: apps/v1
kind: Deployment
metadata:
name: hello-minikube-api
spec:
selector:
matchLabels:
app: hello-minikube-api
replicas: 1
template:
metadata:
labels:
app: hello-minikube-api
spec:
containers:
- name: hello-minikube-api
imagePullPolicy: Never
image: hello-minikube-api
ports:
- containerPort: 80
文件创建完成之后,下面开始使用kubectl进行部署。由于minikube中已经集成了kubectl,所以没有独立安装kubectl。
运行minikube:
minikube start
minikube运行之后使用minikube kubectl --命令可以进行kubectl的操作。譬如获取pods:
minikube kubectl -- get pods
为了方便使用,设置kubectl的alias:
alias kubectl="minikube kubectl --"
使用以下命令完成hello-minikube-api的部署:
#创建部署
kubectl create -f deployment.yaml
#查看部署
kubectl get deployments
#查看pods
kubectl get pods
结果如下图所示:
查看pods发现,hello-minikube-api的状态是ErrImageNeverPull,所以没有正常运行。由于hello-minikube-api的镜像是本地自行构建的,在deployment.yaml中也声明了imagePullPolicy为Never,造成该问题的原因是因为minikube没有从docker中获取到hello-minikube-api的镜像,所以我们需要做一个指向操作,让minikube可以直接从本地docker使用镜像。使用以下命令完成:
minikube docker-env
#系统输出和提示:
export DOCKER_TLS_VERIFY="1"
export DOCKER_HOST="tcp://192.168.49.2:2376"
export DOCKER_CERT_PATH="/home/quanzhange/.minikube/certs"
export MINIKUBE_ACTIVE_DOCKERD="minikube"
# To point your shell to minikube's docker-daemon, run:
# eval $(minikube -p minikube docker-env)
根据上面输出的#To point your shell to minikube's docker-daemon, run: #eval $(minikube -p minikube docker-env) 提示,执行以下命令:
eval $(minikube -p minikube docker-env)
执行完该命令之后,我们需要删除之前创建的minikube相关的部署,并且需要重新构建docker镜像,然后再将之前的deployment重新创建和发布到minikube:
#重新构建镜像
docker build -t hello-minikube-api .
#删除之前创建的deployment
kubectl delete deployment hello-minikube-api
#重新创建部署
kubectl create -f deployment.yaml
#查看Pods
kubectl get pods
运行结果可以看到hello-minikube-api正在运行,如下图所示:
如图所示,容器化的hello-minikube-api目前正在minikube环境中运行,现在通过expose操作将其作为NodePort公开以便外部可以进行访问,并使用minikube获取正在运行的hello-minikube-api的URL:
#公开hello-minikube-api
kubectl expose deployment hello-minikube-api --type=NodePort
#获取hello-minikube-api的URL
minikube service hello-minikube-api --url
#测试请求API的Endpoint
curl http://192.168.49.2:32753/weatherforecast
运行结果如下:
可以看到,通过访问输出的URL正确的获取到了响应信息,以上结果证明hello-minikube-api已经正确启动并运行了。