我将先阐述Docker和Kubernetes的基本概念与优势,再介绍环境搭建、镜像构建、部署应用等实操步骤,最后给出监控与扩展的方法,助你掌握容器化技术。
Docker + Kubernetes容器化方案实践指南
一、引言
在当今数字化时代,应用程序的快速迭代和高效部署成为了企业竞争力的关键因素。容器化技术应运而生,为开发者和运维团队提供了一种便捷、高效的应用交付方式。Docker和Kubernetes作为容器化领域的两大核心技术,前者专注于应用的打包与隔离,后者则擅长容器的编排与管理。两者结合,形成了一套强大的容器化解决方案,能够极大地提升应用的开发、部署和运维效率。本文将详细介绍如何使用Docker和Kubernetes构建一个完整的容器化应用体系,并通过实际案例帮助读者快速上手。
二、Docker与Kubernetes基础
2.1 Docker基础
Docker是一种开源的容器化平台,它允许开发者将应用及其依赖打包成一个可移植的容器,从而实现“Build Once, Run Anywhere”的目标。Docker的核心组件包括:
- 镜像(Image):镜像类似于虚拟机的镜像,是一个只读的模板,包含了运行应用所需的所有文件和配置。例如,一个基于Node.js的Web应用镜像,会包含Node.js运行环境、应用代码以及应用所依赖的各种npm包。镜像可以通过Dockerfile来构建,Dockerfile中定义了镜像的基础镜像、安装的软件包、运行的命令等信息。例如,以下是一个简单的基于Node.js的Dockerfile示例:
# 使用官方的Node.js基础镜像
FROM node:14
# 设置工作目录
WORKDIR /app
# 将package.json和package - lock.json复制到工作目录
COPY package*.json./
# 安装应用依赖
RUN npm install
# 将应用代码复制到工作目录
COPY. /app
# 暴露应用运行的端口
EXPOSE 3000
# 定义容器启动时运行的命令
CMD ["npm", "start"]
- 容器(Container):容器是镜像的运行实例,可被创建、启动、停止和删除。当我们基于一个镜像启动容器时,就相当于创建了一个独立的运行环境,该环境中包含了镜像中的所有内容。每个容器都有自己独立的文件系统、网络空间和进程空间,这使得不同的容器之间相互隔离,互不干扰。例如,我们可以通过以下命令基于刚才构建的Node.js镜像启动一个容器:
-docker run -d -p 3000:3000 my - node - app
其中,-d
参数表示在后台运行容器,-p 3000:3000
表示将容器的3000端口映射到主机的3000端口,这样我们就可以通过主机的IP地址和3000端口来访问容器内运行的应用了。
- 仓库(Repository):仓库是存储镜像的地方,分为公有仓库(如Docker Hub)和私有仓库。公有仓库如Docker Hub上存储了大量的官方和第三方镜像,我们可以方便地从上面拉取所需的镜像。例如,要拉取官方的Nginx镜像,可以使用以下命令:
-
如果企业有自己的特定需求,也可以搭建私有仓库,将企业内部开发的镜像存储在私有仓库中,以保证镜像的安全性和可控性。docker pull nginx
2.2 Kubernetes基础
Kubernetes是Google开源的容器编排引擎,用于自动化容器应用的部署、扩展和管理。其核心概念包括:
- Pod:Pod是Kubernetes中最小的部署单元,一个Pod可以包含一个或多个紧密相关的容器。例如,一个Web应用可能需要一个容器运行应用代码,另一个容器运行数据库,这两个容器可以被打包在同一个Pod中。Pod内的容器共享网络命名空间和存储卷,它们之间可以通过localhost进行高效通信。例如,以下是一个简单的包含两个容器(一个Nginx容器和一个自定义的Web应用容器)的Pod的YAML配置示例:
apiVersion: v1
kind: Pod
metadata:
name: my - web - pod
spec:
containers:
- name: nginx - container
image: nginx
ports:
- containerPort: 80
- name: web - app - container
image: my - web - app - image
ports:
- containerPort: 3000
- Service:Service为一组Pod提供稳定的网络接口,实现服务发现和负载均衡。当我们有多个相同功能的Pod时,通过Service可以将这些Pod暴露为一个统一的服务地址,外部客户端可以通过这个地址访问服务,而无需关心具体是哪个Pod在提供服务。例如,以下是一个将上面的
my - web - pod
暴露为一个Service的YAML配置:
apiVersion: v1
kind: Service
metadata:
name: my - web - service
spec:
selector:
app: my - web - app
ports:
- protocol: TCP
port: 80
targetPort: 3000
type: ClusterIP
这里的selector
字段用于选择要关联的Pod,app: my - web - app
表示选择标签为app=my - web - app
的Pod。ports
字段定义了服务的端口映射,port
是Service对外暴露的端口,targetPort
是Pod内容器实际运行的端口。type: ClusterIP
表示该Service仅在集群内部可访问。
- Deployment:Deployment用于定义Pod的期望状态,支持滚动更新和回滚。通过Deployment,我们可以方便地管理Pod的副本数量、更新策略等。例如,以下是一个定义了上述
my - web - pod
的Deployment的YAML配置:
apiVersion: apps/v1
kind: Deployment
metadata:
name: my - web - deployment
spec:
replicas: 3
selector:
matchLabels:
app: my - web - app
template:
metadata:
labels:
app: my - web - app
spec:
containers:
- name: nginx - container
image: nginx
ports:
- containerPort: 80
- name: web - app - container
image: my - web - app - image
ports:
- containerPort: 3000
replicas
字段指定了期望的Pod副本数量,这里为3个。当我们需要更新应用时,可以通过修改Deployment中的镜像版本,Kubernetes会按照滚动更新策略逐步替换旧的Pod,确保服务的连续性。
- Namespace:Namespace提供逻辑隔离,用于划分不同的资源组。例如,一个企业内部可能有多个团队,每个团队可以使用一个Namespace来管理自己的资源,避免不同团队之间的资源冲突。我们可以通过以下命令创建一个新的Namespace:
-
然后,在创建资源(如Pod、Service等)时,可以通过kubectl create namespace my - team - ns
--namespace
参数指定将资源创建到特定的Namespace中,例如:
-kubectl create - f my - pod.yaml --namespace=my - team - ns
2.3 二者关系
Docker负责应用的容器化封装,将应用及其依赖打包成可移植的容器镜像。Kubernetes则负责容器的编排和管理,它以Docker镜像为基础,通过对Pod、Service等资源的管理,实现容器化应用的全生命周期管理。简单来说,Docker提供了容器化的基础能力,而Kubernetes则在更高层次上对这些容器进行组织和协调,使得大规模的容器化应用部署和管理变得更加高效和可靠。
三、环境搭建
3.1 安装Docker
以Ubuntu系统为例,安装Docker的步骤如下:
- 更新系统软件包索引:
-sudo apt update
- 安装必要的软件包,用于通过HTTPS使用仓库:
-sudo apt install apt - transport - https ca - certificates curl software - properties - common
- 添加Docker官方GPG密钥:
-curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker - archive - keyring.gpg
- 添加Docker仓库到系统:
-echo "deb [arch=amd64 signed - by=/usr/share/keyrings/docker - archive - keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
- 更新软件包索引,并安装Docker:
-
安装完成后,可以通过以下命令验证Docker是否安装成功:sudo apt update sudo apt install docker - ce docker - ce - cli containerd.io
-
如果看到输出了一些关于Docker的信息,说明安装成功。sudo docker run hello - world
3.2 安装Kubernetes
这里我们使用Minikube在本地搭建一个单节点的Kubernetes集群,Minikube适合用于学习和开发环境。安装步骤如下:
- 下载Minikube安装包,根据不同的操作系统选择相应的下载链接,例如在Linux系统中,可以使用以下命令下载:
-curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube - Linux - amd64
- 将下载的二进制文件移动到可执行路径,并添加执行权限:
-sudo mv minikube - Linux - amd64 /usr/local/bin/minikube sudo chmod +x /usr/local/bin/minikube
- 安装kubectl,kubectl是Kubernetes的命令行工具,用于与Kubernetes集群进行交互。在Linux系统中,可以使用以下命令安装:
-curl -LO https://storage.googleapis.com/kubernetes - release/release/$(curl -s https://storage.googleapis.com/kubernetes - release/release/stable.txt)/bin/linux/amd64/kubectl chmod +x./kubectl sudo mv./kubectl /usr/local/bin/kubectl
- 启动Minikube集群:
-
启动过程可能需要一些时间,期间会下载必要的镜像等资源。启动完成后,可以通过以下命令验证集群是否正常运行:minikube start
-
如果看到输出了Kubernetes控制平面的地址等信息,说明集群已成功启动。kubectl cluster - info
四、Docker镜像构建
假设我们有一个简单的Python Flask应用,代码结构如下:
my - flask - app/
├── app.py
├── requirements.txt
└── templates/
└── index.html
其中app.py
是应用的主程序,requirements.txt
记录了应用所依赖的Python包,templates
目录存放HTML模板文件。
4.1 创建Dockerfile
在my - flask - app
目录下创建一个名为Dockerfile
的文件,内容如下:
# 使用官方的Python基础镜像
FROM python:3.9
# 设置工作目录
WORKDIR /app
# 将requirements.txt复制到工作目录
COPY requirements.txt.
# 安装应用依赖
RUN pip install - r requirements.txt
# 将应用代码复制到工作目录
COPY. /app
# 暴露应用运行的端口
EXPOSE 5000
# 定义容器启动时运行的命令
CMD ["python", "app.py"]
这个Dockerfile
的含义如下:
FROM python:3.9
:指定基础镜像是官方的Python 3.9镜像。WORKDIR /app
:设置容器内的工作目录为/app
。COPY requirements.txt.
:将本地的requirements.txt
文件复制到容器内的当前目录(即/app
)。RUN pip install - r requirements.txt
:在容器内执行命令,安装requirements.txt
中列出的所有Python包。COPY. /app
:将本地当前目录(my - flask - app
)下的所有文件复制到容器内的/app
目录。EXPOSE 5000
:声明容器将在5000端口上运行应用,这只是一个声明,实际端口映射在启动容器时进行。CMD ["python", "app.py"]
:定义容器启动时要执行的命令,这里是运行app.py
文件来启动Flask应用。
4.2 构建镜像
在my - flask - app
目录下,执行以下命令构建镜像:
-
docker build -t my - flask - app:latest.
其中-t
参数用于给镜像打标签,my - flask - app:latest
表示镜像名为my - flask - app
,标签为latest
,最后的.
表示Dockerfile所在的路径为当前目录。构建过程中,Docker会按照Dockerfile
中的指令逐步执行,下载基础镜像、安装依赖、复制文件等,这个过程可能需要一些时间,取决于网络速度和依赖包的数量。构建完成后,可以通过以下命令查看本地镜像列表:
-
docker images
可以看到my - flask - app:latest
镜像已经在列表中。
五、Kubernetes部署应用
5.1 创建Deployment
在my - flask - app
目录下创建一个名为deployment.yaml
的文件,用于定义Kubernetes Deployment,内容如下:
apiVersion: apps/v1
kind: Deployment
metadata:
name: my - flask - deployment
spec:
replicas: 3
selector:
matchLabels:
app: my - flask - app
template:
metadata:
labels:
app: my - flask - app
spec:
containers:
- name: my - flask - container
image: my - flask - app:latest
ports:
- containerPort: 5000
这个Deployment配置的含义如下:
apiVersion: apps/v1
:指定Kubernetes API版本。kind: Deployment
:定义资源类型为Deployment。metadata.name: my - flask - deployment
:给Deployment命名为my - flask - deployment
。spec.replicas: 3
:指定期望的Pod副本数量为3个,这意味着Kubernetes会确保集群中始终运行3个该应用的实例。spec.selector.matchLabels.app: my - flask - app
:通过标签选择器选择要管理的Pod,这里选择标签为app=my - flask - app
的Pod。spec.template.metadata.labels.app: my - flask - app
:定义Pod模板的标签,这个标签要与上面的选择器匹配,以便Deployment能够正确管理Pod。spec.template.spec.containers
:定义Pod内的容器信息,这里只有一个容器。name: my - flask - container
:给容器命名为my - flask - container
。image: my - flask - app:latest
:指定容器使用的镜像为我们刚才构建的my - flask - app:latest
。ports.containerPort: 5000
:指定容器内应用运行的端口为5000。
5.2 创建Service
创建一个名为service.yaml
的文件,用于定义Kubernetes Service,内容如下:
apiVersion: v1
kind: Service
metadata:
name: my - flask - service
spec:
selector:
app: my - flask - app
ports:
- protocol: TCP
port: 80
targetPort: 5000
type: NodePort
这个Service配置的含义如下:
apiVersion: v1
:指定Kubernetes API版本。kind: Service
:定义资源类型为Service。metadata.name: my - flask - service
:给Service命名为my - flask - service
。spec.selector.app: my - flask - app
:通过标签选择器选择要关联的Pod,这里选择标签为app=my - flask - app
的Pod,也就是我们刚才在Deployment中定义的Pod。spec.ports
:定义端口映射信息。protocol: TCP
:使用TCP协议。port: 80
:Service对外暴露的端口为80,外部客户端可以通过这个端口访问服务。targetPort: 5000
:Pod内容器实际运行的端口为5000,Service会将外部发往80端口的请求转发到Pod的5000端口。
type: NodePort
:指定Service的类型为NodePort,这种类型会在集群节点上分配一个随机端口(默认为30000 - 32767之间),并将该端口映射到Service的port
字段指定的端口(这里是80),这样外部可以通过<节点IP>:<随机分配的端口>
来访问服务。
5.3 部署应用
在my - flask - app
目录下,执行以下命令部署应用:
-
kubectl apply - f deployment.yaml
kubectl apply - f service.yaml
kubectl apply
命令用于将定义的资源配置应用到Kubernetes集群中。执行完成后,可以通过以下命令查看Deployment的状态:
-
kubectl get deployments
可以看到my - flask - deployment
的相关信息,包括副本数量、就绪状态等。通过以下命令查看Pod的状态:
-
kubectl get pods
可以看到3个`.
Docker 容器化,Kubernetes 部署,容器核心技术,企业级容器应用,容器化全方案,云原生部署,微服务容器化,Docker 实战,K8s 应用实践,容器技术解析,企业容器方案,云原生容器,Kubernetes 核心技术,容器部署实践,DevOps 容器架构
代码获取方式
https://pan.quark.cn/s/14fcf913bae6