- 作者:老汪软件技巧
- 发表时间:2024-11-23 21:04
- 浏览量:
容器化和容器编排技术已成为构建、部署和管理应用的标准。特别是 Docker 和 Kubernetes,它们的结合使得应用的部署、扩展和管理变得更加高效和自动化。本文将介绍如何将一个简单的 Java 应用容器化并部署到 Kubernetes 集群中,同时解释 Docker 和 Kubernetes 的核心概念及其应用。
1. Docker 核心概念理解
Docker 是一个开源的容器化平台,用于自动化应用的部署、扩展和管理。它通过将应用程序及其依赖项打包到一个可移植的容器中,解决了“在我的机器上能运行”这一问题。Docker 的核心概念包括:
1.1 镜像 (Image)
镜像是 Docker 中的一个只读模板,包含了运行一个应用所需的所有文件、环境变量和配置。镜像是容器的蓝图。每个镜像都是根据一个 Dockerfile 来构建的。
1.2 容器 (Container)
容器是镜像的运行实例,是一个轻量级的虚拟化环境,能够隔离应用及其依赖。容器是在 Docker 引擎上运行的,它是可移植的、可执行的,且具有较低的开销。
1.3 Dockerfile
Dockerfile 是一组定义如何构建 Docker 镜像的指令。例如,可以在 Dockerfile 中指定基础镜像、复制应用文件、安装依赖项等。
1.4 卷 (Volumes)
卷是用于持久化数据的机制,确保容器即使被删除,数据也不会丢失。Docker 提供了简单的方式将容器内的数据挂载到宿主机或外部存储上。
1.5 网络 (Networking)
Docker 提供了多种网络模式,允许容器相互通信。常见的网络模式包括 bridge、host 和 overlay,用于处理不同的应用场景。
2. Docker 安装
官方文档地址:/engine/inst…
2.1 卸载旧版本的 Docker
首先,卸载系统中已有的旧版本 Docker(如果有的话):
sudo yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
2.2 设置 Docker 的 YUM 源(二选一)
您可以选择设置阿里云的镜像源,速度较快(推荐),或者使用官方源。
sudo yum install -y yum-utils
sudo yum-config-manager \
--add-repo \
http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
如果不使用阿里云镜像源,可以设置官方源,但这可能会遇到网络连接等问题:
sudo yum install -y yum-utils
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
2.3 安装 Docker
安装 Docker 相关组件:
sudo yum install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
如果您希望安装 Docker 的指定版本(例如 18.0),可以通过以下命令安装:
sudo yum install docker-ce-18.06.3.ce docker-ce-cli-18.06.3.ce containerd.io docker-buildx-plugin docker-compose-plugin
请注意,上述命令安装的是 18.06.3 版本的 Docker。如果您需要其他具体版本的 Docker,可以根据需要替换版本号。
2.4 启动 Docker 服务
安装完成后,启动 Docker 服务:
sudo systemctl start docker
2.5 设置 Docker 开机自启动
为了确保 Docker 在系统启动时自动启动,可以启用开机自启动:
sudo systemctl enable docker
2.6 查看 Docker 版本信息
最后,您可以通过以下命令检查 Docker 是否成功安装及查看版本信息:
docker -v
docker info
2.7 配置镜像加速器
对于 Docker 客户端版本大于 1.10.0 的用户,可以通过修改 Docker 的 daemon.json 配置文件来使用加速器。
2.7.1 打开配置文件
执行以下命令,打开 /etc/docker/daemon.json 配置文件:
sudo vim /etc/docker/daemon.json
2.7.2 编辑配置文件
按 i 键进入编辑模式,添加以下内容,并保存:
{
"registry-mirrors": [
"https://mirror.ccs.tencentyun.com"
]
}
这个配置将 Docker 镜像加速器设置为腾讯云的镜像源,以加速镜像的下载。
2.7.3 重启 Docker
配置完成后,执行以下命令重启 Docker 服务(以 CentOS 7 为例):
sudo systemctl restart docker
2.7.4 查看当前 Docker 配置
重启 Docker 后,可以运行以下命令检查配置是否生效:
docker info
在输出的信息中,您应该能看到类似以下部分,说明镜像加速器配置成功:
Registry Mirrors:
https://mirror.ccs.tencentyun.com
2.7.5 验证 Docker 安装
为了验证 Docker 是否正常工作,可以运行以下命令:
sudo docker run hello-world
如果一切配置正确,您将看到 Docker 的欢迎信息,表示 Docker 已成功安装并正常运行。
3. 新建 Spring Boot 项目并构建 Docker 镜像3.1 配置 Spring Boot 项目
server:
port: 8080 # 默认端口,可以不写
Dockerfile 文件内容: (在 pom.xml 中指定了打包文件名为 app)
FROM openjdk:8u221-jre
# 设置工作目录
WORKDIR /tmp
# 将 Spring Boot JAR 文件添加到容器中
COPY spring-boot-docker-1.0.jar /app/app.jar
# 暴露端口(假设 Spring Boot 应用默认使用 8080 端口)
EXPOSE 8080
# 设置容器启动时的命令
ENTRYPOINT ["java", "-Djava.security.egd=file:/dev/./urandom", "-jar", "/app/app.jar"]
3.2 构建 Docker 镜像
构建成功后,执行以下命令查看已创建的镜像:
docker build -t spring-boot-docker .
成功后执行下 docker images,可以看到我们刚创建的镜像:
3.3 运行 Docker 容器
使用以下命令来运行镜像并启动容器:
docker run -d -p 8080:8080 --name spring-boot-container spring-boot-docker
3.4 参数说明:3.5 验证 Docker 容器运行
如果一切顺利,您的 Spring Boot 应用将在 Docker 容器中运行,并可以通过 :8080 访问。您可以通过以下命令检查容器的状态:
docker ps
这个命令会列出正在运行的容器,应该能看到类似于下面的输出:
3.6 访问你的应用
如果你的 Spring Boot 应用在 8080 端口上监听,访问 :8080 就能看到应用运行的结果。
3.7 查看容器日志
如果您想查看容器的输出日志,可以使用以下命令:
docker logs spring-boot-container
这将显示容器的运行日志,可以帮助你排查应用是否成功启动。
这将显示容器的运行日志,可以帮助你排查应用是否成功启动。
3.8 停止并删除容器(如果需要)
如果你需要停止并删除容器,可以使用以下命令:
docker stop spring-boot-container
docker rm spring-boot-container
4. K8s 环境配置4.1 Kubernetes 核心概念理解
Kubernetes 是一个容器编排平台,旨在自动化容器化应用的部署、扩展和管理。它能够协调和管理成千上万的容器,提供高可用性、自动扩展、负载均衡等特性。
4.1.1 Pod
Pod 是 Kubernetes 中的基本调度单位。每个 Pod 可以包含一个或多个容器,这些容器共享网络和存储资源。Pod 是 Kubernetes 用来部署和管理容器的基本单元。
4.1.2 Deployment
Deployment 是 Kubernetes 中用于管理应用部署的资源。它允许用户声明应用的期望状态(如副本数、镜像版本等),并且 Kubernetes 会自动保证实际状态与期望状态一致。Deployment 支持滚动更新和回滚等功能。
4.1.3 Service
Service 是 Kubernetes 中的一个抽象层,它为一组 Pod 提供稳定的访问接口。Service 的类型可以是 ClusterIP(仅在集群内部可访问)、NodePort(集群外部可以访问)或 LoadBalancer(通过云提供商的负载均衡器访问)。
4.1.4 ReplicaSet
ReplicaSet 确保指定数量的 Pod 副本始终在运行。它通常由 Deployment 管理,保证应用的高可用性。
4.1.5 Ingress
Ingress 是 Kubernetes 中的一种资源,用于管理 HTTP 和 HTTPS 流量的路由。它提供了基于 URL 的路由规则,可以将外部流量引导到集群内部的 Service。
在每台机器上,分别执行以下步骤:
4.2 关闭防火墙
systemctl stop firewalld
systemctl disable firewalld
4.2. 关闭 SELinux
setenforce 0
sed -i 's/enforcing/disabled/' /etc/selinux/config
4.3 关闭 Swap
swapoff -a
sed -ri 's/.*swap.*/#&/' /etc/fstab
4.4 设置每个节点的主机名
在每个节点上,设置主机名:
hostnamectl set-hostname
例如,在 Master 节点上,可以执行:
hostnamectl set-hostname k8smaster
4.5 在 Master 节点上添加 Hosts
在 Master 节点上,将各节点的 IP 地址和主机名添加到 /etc/hosts 文件中。例如:
cat >> /etc/hosts << EOF
192.168.1.3 k8smaster
EOF
4.6 配置 Kubernetes 节点的网络
为了确保桥接的 IPv4 流量能够正确传递到 iptables 链中,创建一个新的配置文件 /etc/sysctl.d/k8s.conf:
cat > /etc/sysctl.d/k8s.conf << EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
然后执行以下命令使配置生效:
sysctl --system
4.7 所有节点安装 kubeadm / kubelet4.7.1 添加腾讯云 YUM 源
在每个节点上,执行以下命令来添加腾讯云的 Kubernetes YUM 镜像源:
cat > /etc/yum.repos.d/kubernetes.repo << EOF
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.cloud.tencent.com/kubernetes/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=0
repo_gpgcheck=0
gpgkey=https://mirrors.cloud.tencent.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.cloud.tencent.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF
4.7.2 安装 kubeadm、kubelet 和 kubectl
执行以下命令安装指定版本的 Kubernetes 工具:
yum install -y kubelet-1.18.0 kubeadm-1.18.0 kubectl-1.18.0
安装完成后,启用并启动 kubelet 服务:
systemctl enable kubelet
4.8 部署 K8s Master 节点4.8.1 拉取 Kubernetes 镜像
在 Master 节点上,使用 kubeadm 命令初始化 Kubernetes 集群并拉取必要的镜像:
kubeadm init --apiserver-advertise-address=192.168.1.3 \
--image-repository registry.aliyuncs.com/google_containers \
--kubernetes-version v1.18.0 \
--service-cidr=10.96.0.0/12 \
--pod-network-cidr=10.244.0.0/16
--image-repository /google_containers:
--kubernetes-version v1.18.0:
--service-cidr=10.96.0.0/12:
--pod-network-cidr=10.244.0.0/16:
可能会遇到错误:[ERROR FileContent--proc-sys-net-ipv4-ip_forward]: /proc/sys/net/ipv4/ip_forward contents are not set to 1 [preflight] If you know what you are doing, you can make a check non-fatal with --ignore-preflight-errors=... To see the stack trace of this error execute with --v=5 or higher
Docker 使用的 cgroup 驱动不推荐:
/proc/sys/net/ipv4/ip_forward 文件未设置为 1:
4.8.2 解决方案
更改 Docker 的 cgroup 驱动:为了使 Docker 与 Kubernetes 配合良好,您需要将 Docker 的 cgroup 驱动从 cgroupfs 更改为 systemd,这是 Kubernetes 推荐的设置。请按照以下步骤进行修改:
打开 Docker 的配置文件 /etc/docker/daemon.json(如果该文件不存在,可以创建一个新的文件):
sudo vi /etc/docker/daemon.json
然后,添加以下内容,指定使用 systemd 作为 cgroup 驱动:
{
"exec-opts": ["native.cgroupdriver=systemd"]
}
修改完成后,重新启动 Docker 服务,使配置生效:
sudo systemctl restart docker
您可以使用以下命令确认 Docker 是否正在使用 systemd 作为 cgroup 驱动:
sudo docker info | grep -i cgroup
错误信息表明 Kubernetes 启动过程中拉取镜像失败,具体错误是:unknown: image repo not found,即 /google_containers 镜像库中没有找到相应的 Kubernetes 镜像。
3.8.3 更改为其他可靠的镜像源
如果腾讯云的镜像库中确实没有相关镜像,你可以尝试使用其他国内的镜像源,例如:
例如,使用阿里云镜像源,修改 kubeadm init 命令如下:
kubeadm init --apiserver-advertise-address=81.70.252.90 \
--image-repository registry.aliyuncs.com/google_containers \
--kubernetes-version v1.18.0 \
--service-cidr=10.96.0.0/12 \
--pod-network-cidr=10.244.0.0/16
4.8.4 手动拉取 Kubernetes 镜像
如果你找到了可用的镜像源,但 kubeadm 仍然无法拉取镜像,你可以手动拉取并加载这些镜像。可以使用如下命令手动拉取镜像:
docker pull registry.aliyuncs.com/google_containers/kube-apiserver:v1.18.0
docker pull registry.aliyuncs.com/google_containers/kube-controller-manager:v1.18.0
docker pull registry.aliyuncs.com/google_containers/kube-scheduler:v1.18.0
docker pull registry.aliyuncs.com/google_containers/kube-proxy:v1.18.0
docker pull registry.aliyuncs.com/google_containers/pause:3.2
docker pull registry.aliyuncs.com/google_containers/etcd:3.4.3-0
docker pull registry.aliyuncs.com/google_containers/coredns:1.6.7
docker image ls
4.8.5 重置集群 (出现错误再操作,否则请略过!!!)
然后重新初始化 Kubernetes:如果没有其他方法解决,可以尝试手动清理 Kubernetes 配置文件和相关资源后,再次执行 kubeadm reset。
kubeadm reset
执行以下命令清理节点配置和证书:
rm -rf /etc/kubernetes/*
rm -rf /var/lib/etcd
rm -rf ~/.kube
4.8.6 如果拉取成功,会出现如下信息:
Your Kubernetes control-plane has initialized successfully!
To start using your cluster, you need to run the following as a regular user:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
...
Then you can join any number of worker nodes by running the following on each as root:...
此时,请按照提示操作。
4.8.7 执行提示信息
在 Master 节点上执行以下命令:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
使用 kubectl 工具查看节点状态:
kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8smaster NotReady master 9m08s v1.18.0
在 Master 节点上执行以下命令应用 Flannel 网络插件:
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
4.8.8 拉取 nginx 作为测试创建一个 nginx Pod:
kubectl create deployment nginx --image=nginx
deployment.apps/nginx created
查看 nginx Pod 状态,确保镜像下载完毕并运行:
kubectl get pod
NAME READY STATUS RESTARTS AGE
nginx-g463146546-524pw 1/1 Running 0 68s
对外暴露端口:
kubectl expose deployment nginx --port=80 --type=NodePort
service/nginx exposed
查看暴露后的服务,确认对外暴露的端口为 30901:
kubectl get pod,svc
NAME READY STATUS RESTARTS AGE
pod/nginx-g463146546-524pw 1/1 Running 0 2m54s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.27.0.1 443/TCP 155m
service/nginx NodePort 10.106.145.01 80:30901/TCP 38s
此时,您可以通过访问集群中任意节点的 30901 端口来验证是否能够成功访问 nginx,如果能够访问,说明集群已配置完成并正常运行。
5. Harbor安装5.1 下载
首先从Harbor的GitHub Releases页面下载离线安装包(版本v2.6.0):
wget https://github.com/goharbor/harbor/releases/download/v2.6.0/harbor-offline-installer-v2.6.0.tgz
5.2. 解压
将下载的安装包解压到指定目录:
tar -xzvf harbor-offline-installer-v2.6.0.tgz -C /usr/local/
5.3. 配置
复制并修改harbor.yml配置文件:
cp harbor.yml.tmpl harbor.yml
编辑harbor.yml文件,配置Harbor的地址、端口、数据库等信息。具体内容可以根据需求进行调整。
5.4. 启动Harbor
# Step 1: 进入harbor目录
cd /xxxxx/xxxxx/harbor
# Step 2: 执行prepare命令,进入准备启动阶段,这里会检测你的环境等
./prepare
# Step 3: 准备阶段完成后,启动下载harbor,这里会下载并运行7个镜像
./install.sh
启动后,你可以通过浏览器访问 进行登录。
5.5 Harbor使用5.5.1 创建项目
创建用户:在Harbor的Web界面中,可以创建不同的用户并设置角色,通常包括管理员和普通用户。
创建私有项目:进入Harbor Web界面,选择"Projects"并点击"New Project"来创建一个新的私有项目。
给项目追加用户:在创建项目后,可以通过设置项目的权限,将其他用户追加到该项目中。权限包括管理员、开发者、只读等。
切换用户:用户登录后,可以在界面上切换不同的账户。
5.5.2 发布镜像到Harbor
修改daemon.json:配置Docker支持Harbor作为镜像仓库。在Docker主机上编辑daemon.json,加入Harbor仓库地址:
{
"registry-mirrors": ["https://xxxxxxxxx.mirror.aliyuncs.com"],
"insecure-registries": ["172.16.52.10:80"]
}
然后重启Docker服务:
systemctl restart docker
登录Harbor:在本地机器上使用Docker CLI登录到Harbor仓库:
docker login -u 用户名 -p 密码 172.16.52.10:80
制作镜像:使用Docker构建一个镜像并标记为Harbor仓库的格式:
docker build -t 172.16.52.10:80/my-repo/my-spring-boot-app:latest .
推送镜像到Harbor:将本地构建的镜像推送到Harbor:
docker push 172.16.52.10:80/my-repo/my-spring-boot-app:latest .
推送过程中,你将看到每一层的推送进度,推送成功后,镜像会出现在Harbor的项目中。
推送已有镜像:如果需要推送已有镜像,只需修改镜像名称并推送:
docker tag demo:v1.0.0 172.16.52.10:80/my-repo/my-spring-boot-app:latest .
5.5.3 拉取镜像
配置daemon.json:配置Docker的镜像仓库,重启Docker。
拉取镜像:使用Docker命令从Harbor仓库拉取镜像:
docker pull 172.16.52.10:80/my-repo/my-spring-boot-app:latest .
5.6 额外说明6. 创建 Kubernetes 部署和服务配置文件
接下来,创建 Kubernetes 的 deployment.yaml 和 service.yaml 配置文件。
6.1 deployment.yaml
在项目目录下创建 deployment.yaml,用于定义 Kubernetes 部署配置。
apiVersion: apps/v1
kind: Deployment
metadata:
name: demo-app-deployment
spec:
replicas: 2 # 初始副本数
selector:
matchLabels:
app: demo-app
template:
metadata:
labels:
app: demo-app
spec:
containers:
- name: demo-app
image: 172.16.52.10:80/my-repo/my-spring-boot-app:latest # 从 Harbor 拉取镜像
ports:
- containerPort: 8080 # Spring Boot 默认端口
6.2 service.yaml
创建一个 service.yaml 文件,用于定义 Kubernetes 服务配置,确保应用可以通过服务访问。
apiVersion: v1
kind: Service
metadata:
name: demo-app-service
spec:
selector:
app: demo-app
ports:
- protocol: TCP
port: 80 # 服务暴露的端口
targetPort: 8080 # 容器内部的端口
type: LoadBalancer # 使用 LoadBalancer 类型的服务
6.3. 部署应用到 Kubernetes 集群6.3.1 应用部署和服务配置
使用 kubectl 命令应用配置文件,将应用部署到 Kubernetes 集群中:
kubectl apply -f deployment.yaml
kubectl apply -f service.yaml
6.4 验证部署状态6.4.1 查看 Pod 状态
执行以下命令来检查 Pod 是否启动成功:
kubectl get pods
NAME READY STATUS RESTARTS AGE
demo-app-deployment-7cd6d6b4f6-p5g7x 1/1 Running 0 2m
demo-app-deployment-7cd6d6b4f6-r8wsd 1/1 Running 0 2m
这里,READY 列中的值表示每个 Pod 中容器是否成功启动。如果值是 1/1,表示该 Pod 的容器已成功启动并运行。
6.4.2 查看服务状态
执行以下命令查看服务的状态:
kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
demo-app-service LoadBalancer 10.96.1.100 80:31234/TCP 2m
6.4.3 访问应用
如果服务类型是 LoadBalancer,你可以通过浏览器或命令行访问外部 IP 来验证应用是否正常运行:
curl http://
如果应用正常,应该能看到你的 Spring Boot 应用的首页或返回的数据。
6.5 结果
显示应用已成功部署并通过负载均衡器暴露:
查看 Pods 状态:
kubectl get pods
NAME READY STATUS RESTARTS AGE
demo-app-deployment-7cd6d6b4f6-p5g7x 1/1 Running 0 2m
demo-app-deployment-7cd6d6b4f6-r8wsd 1/1 Running 0 2m
查看服务状态:
kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
demo-app-service LoadBalancer 10.96.1.100 172.16.52.20 80:31234/TCP 3m
通过外部 IP 访问应用:
curl http://172.16.52.20
表示 Spring Boot 应用已经成功部署并能够通过负载均衡器的外部 IP 进行访问。
6.6. 清理资源
如果需要删除部署的应用和服务,可以使用以下命令:
kubectl delete -f deployment.yaml
kubectl delete -f service.yaml
6.7 总结
通过这些步骤,你已经成功地:
构建并推送 Docker 镜像到 Harbor 仓库;使用 Kubernetes 部署应用,并将其暴露为服务;通过外部 IP 访问已部署的 Spring Boot 应用。