CRI-O教程#
技术介绍#
CRI-O是一个轻量级的容器运行时,专为Kubernetes设计,实现了Kubernetes容器运行时接口(CRI)。它提供了一个与Kubernetes完全兼容的容器运行时环境,专注于简单性、安全性和性能。CRI-O使用OCI(Open Container Initiative)兼容的运行时,如runc,来运行容器。
CRI-O核心概念#
- 容器:运行在隔离环境中的应用
- 镜像:容器的只读模板
- Pod:Kubernetes中的Pod概念,包含一个或多个容器
- 运行时:执行容器的底层运行时,如runc
- 存储:容器的存储管理
- 网络:容器的网络配置
CRI-O架构#
- 核心组件:CRI-O daemon、OCI运行时、镜像管理
- API:Kubernetes CRI接口
- 集成:与Kubernetes无缝集成
- 插件系统:存储、网络、监控等插件
入门级使用#
安装CRI-O#
在不同操作系统上安装CRI-O:
# Ubuntu/Debian
# 添加CRI-O仓库
. /etc/os-release
echo "deb https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/xUbuntu_${VERSION_ID}/ /" | sudo tee /etc/apt/sources.list.d/devel:kubic:libcontainers:stable.list
curl -L https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/xUbuntu_${VERSION_ID}/Release.key | sudo apt-key add -
# 安装CRI-O
apt-get update
apt-get install cri-o cri-o-runc
# CentOS/RHEL
# 添加CRI-O仓库
yum-config-manager --add-repo=https://cbs.centos.org/repos/paas7-crio-311-candidate/x86_64/os/
# 安装CRI-O
yum install cri-o
# 启动CRI-O服务
systemctl start crio
systemctl enable crio
# 验证安装
crio --version
crictl version基本CRI-O命令#
使用CRI-O的基本命令:
# 查看CRI-O版本
crio --version
# 查看crictl版本
crictl version
# 查看CRI-O状态
systemctl status crio
# 查看镜像
crictl images
# 拉取镜像
crictl pull docker.io/library/ubuntu:20.04
# 查看Pod
crictl pods
# 查看容器
crictl containers
# 运行容器
# 首先创建Pod sandbox
POD_ID=$(crictl runp pod-config.json)
# 然后在Pod中运行容器
CONTAINER_ID=$(crictl create $POD_ID container-config.json pod-config.json)
crictl start $CONTAINER_ID
# 停止容器
crictl stop $CONTAINER_ID
crictl rm $CONTAINER_ID
# 停止Pod sandbox
crictl stopp $POD_ID
crictl rmp $POD_ID配置文件#
配置CRI-O:
# 查看CRI-O配置
cat /etc/crio/crio.conf
# 配置示例
# /etc/crio/crio.conf
[crio.runtime]
runtime_path = "/usr/bin/runc"
runtime_root = "/run/runc"
runtime_engine = "runc"
runtime_mode = "oci"
[crio.image]
default_transport = "docker://"
[crio.network]
network_dir = "/etc/cni/net.d"
plugin_dirs = ["/opt/cni/bin"]
# 重启CRI-O服务
systemctl restart crio初级使用#
CRI-O镜像管理#
管理CRI-O镜像:
# 查看镜像
crictl images
# 拉取镜像
crictl pull docker.io/library/ubuntu:20.04
# 推送镜像
crictl push docker.io/library/ubuntu:20.04
# 删除镜像
crictl rmi docker.io/library/ubuntu:20.04
# 查看镜像详情
crictl inspecti docker.io/library/ubuntu:20.04
# 清理未使用的镜像
crictl rmi --pruneCRI-O容器管理#
管理CRI-O容器:
# 查看容器
crictl containers
# 创建容器
# 首先创建Pod sandbox配置
cat > pod-config.json <<EOF
{
"metadata": {
"name": "sandbox",
"namespace": "default",
"attempt": 1,
"uid": "hdishd83djaidwnduwk28bcsb"
},
"log_directory": "/tmp",
"linux": {}
}
EOF
# 创建容器配置
cat > container-config.json <<EOF
{
"metadata": {
"name": "container"
},
"image": {
"image": "docker.io/library/ubuntu:20.04"
},
"command": ["/bin/bash", "-c", "echo hello world"],
"linux": {}
}
EOF
# 运行Pod sandbox
POD_ID=$(crictl runp pod-config.json)
# 创建容器
CONTAINER_ID=$(crictl create $POD_ID container-config.json pod-config.json)
# 启动容器
crictl start $CONTAINER_ID
# 查看容器日志
crictl logs $CONTAINER_ID
# 进入容器
crictl exec -i -t $CONTAINER_ID /bin/bash
# 停止容器
crictl stop $CONTAINER_ID
crictl rm $CONTAINER_ID
# 停止Pod sandbox
crictl stopp $POD_ID
crictl rmp $POD_IDCRI-O网络配置#
配置CRI-O网络:
# 查看网络配置
ls /etc/cni/net.d/
# 创建CNI网络配置
cat > /etc/cni/net.d/10-bridge.conf <<EOF
{
"cniVersion": "0.3.1",
"name": "bridge",
"type": "bridge",
"bridge": "cni0",
"isGateway": true,
"ipMasq": true,
"ipam": {
"type": "host-local",
"subnet": "10.88.0.0/16",
"routes": [
{
"dst": "0.0.0.0/0"
}
]
}
}
EOF
# 重启CRI-O服务
systemctl restart crio
# 测试网络
# 创建Pod和容器,然后测试网络连接中级使用#
CRI-O运行时配置#
配置CRI-O运行时:
# 编辑CRI-O配置
vim /etc/crio/crio.conf
# 配置runc运行时
[crio.runtime]
runtime_path = "/usr/bin/runc"
runtime_root = "/run/runc"
runtime_engine = "runc"
runtime_mode = "oci"
# 配置gVisor运行时
# 安装gVisor
gcurl -fsSL https://gvisor.dev/archive/master/latest/x86_64/releases/runsc | sudo tee /usr/local/bin/runsc > /dev/null
sudo chmod +x /usr/local/bin/runsc
# 配置gVisor运行时
[crio.runtime.runtimes.runsc]
runtime_path = "/usr/local/bin/runsc"
runtime_type = "oci"
runtime_engine = ""
runtime_root = "/run/runsc"
# 重启CRI-O服务
systemctl restart crio
# 使用gVisor运行时
# 在容器配置中指定runtime_handlerCRI-O存储配置#
配置CRI-O存储:
# 编辑CRI-O配置
vim /etc/crio/crio.conf
# 配置存储
[crio.image]
default_transport = "docker://"
pause_image = "k8s.gcr.io/pause:3.2"
pause_command = "/pause"
[crio.runtime]
runtime_path = "/usr/bin/runc"
runtime_root = "/run/runc"
runtime_engine = "runc"
runtime_mode = "oci"
# 配置存储后端
[crio.storage]
storage_driver = "overlay"
storage_option = [
"overlay2.override_kernel_check=true"
]
# 重启CRI-O服务
systemctl restart crioCRI-O与Kubernetes集成#
将CRI-O与Kubernetes集成:
# 安装kubeadm、kubelet、kubectl
apt-get update
apt-get install -y kubelet kubeadm kubectl
# 配置kubelet使用CRI-O
cat > /etc/default/kubelet <<EOF
KUBELET_EXTRA_ARGS=--container-runtime=remote --container-runtime-endpoint=unix:///var/run/crio/crio.sock
EOF
# 初始化Kubernetes集群
kubeadm init --pod-network-cidr=10.244.0.0/16
# 配置kubectl
mkdir -p $HOME/.kube
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
chown $(id -u):$(id -g) $HOME/.kube/config
# 安装网络插件
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
# 查看节点状态
kubectl get nodes
# 查看Pod状态
kubectl get pods --all-namespaces中上级使用#
CRI-O性能优化#
优化CRI-O性能:
# 编辑CRI-O配置
vim /etc/crio/crio.conf
# 优化运行时
[crio.runtime]
runtime_path = "/usr/bin/runc"
runtime_root = "/run/runc"
runtime_engine = "runc"
runtime_mode = "oci"
runtimes = [
"runc",
"runsc"
]
# 优化存储
[crio.storage]
storage_driver = "overlay2"
storage_option = [
"overlay2.override_kernel_check=true",
"overlay2.size=10G"
]
# 优化网络
[crio.network]
network_dir = "/etc/cni/net.d"
plugin_dirs = ["/opt/cni/bin"]
# 重启CRI-O服务
systemctl restart crio
# 重启kubelet服务
systemctl restart kubeletCRI-O安全配置#
配置CRI-O安全选项:
# 编辑CRI-O配置
vim /etc/crio/crio.conf
# 配置安全选项
[crio.runtime]
runtime_path = "/usr/bin/runc"
runtime_root = "/run/runc"
runtime_engine = "runc"
runtime_mode = "oci"
# 配置默认安全上下文
[crio.runtime.default]
security_context = {
"namespace_options": {
"network_namespace": "",
"pid_namespace": "",
"ipc_namespace": "",
"mount_namespace": "",
"user_namespace": ""
},
"capabilities": {
"add": [],
"drop": ["ALL"]
},
"selinux_options": {
"user": "",
"role": "",
"type": "",
"level": ""
}
}
# 重启CRI-O服务
systemctl restart crioCRI-O监控#
监控CRI-O:
# 启用CRI-O指标
# 编辑CRI-O配置
vim /etc/crio/crio.conf
# 启用指标
[crio.metrics]
enable_metrics = true
metrics_port = 9537
# 重启CRI-O服务
systemctl restart crio
# 使用Prometheus监控CRI-O
# 创建Prometheus配置
cat > prometheus.yml <<EOF
global:
scrape_interval: 15s
scrape_configs:
- job_name: 'crio'
static_configs:
- targets: ['localhost:9537']
EOF
# 运行Prometheus
podman run -d --name prometheus \
-p 9090:9090 \
-v ./prometheus.yml:/etc/prometheus/prometheus.yml \
prom/prometheus
# 使用Grafana查看监控数据
podman run -d --name grafana \
-p 3000:3000 \
grafana/grafana高级使用#
CRI-O集群管理#
管理CRI-O集群:
# 在多个节点上安装CRI-O
# 节点1
ssh node1 "apt install cri-o cri-o-runc"
# 节点2
ssh node2 "apt install cri-o cri-o-runc"
# 节点3
ssh node3 "apt install cri-o cri-o-runc"
# 配置Kubernetes集群
# 在主节点上初始化集群
kubeadm init --pod-network-cidr=10.244.0.0/16
# 在工作节点上加入集群
kubeadm join <master-ip>:6443 --token <token> --discovery-token-ca-cert-hash <hash>
# 查看集群状态
kubectl get nodes
# 部署应用
kubectl apply -f deployment.yaml
# 查看应用状态
kubectl get podsCRI-O与Istio集成#
将CRI-O与Istio集成:
# 安装Istio
curl -L https://istio.io/downloadIstio | sh -
cd istio-*
export PATH=$PWD/bin:$PATH
# 部署Istio
istioctl install --set profile=demo -y
# 标记命名空间以启用Istio
kubectl label namespace default istio-injection=enabled
# 部署应用
kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml
# 查看应用状态
kubectl get pods
# 访问应用
kubectl get svc istio-ingressgateway -n istio-systemCRI-O安全审计#
进行CRI-O安全审计:
# 检查CRI-O配置
cat /etc/crio/crio.conf
# 检查容器安全上下文
crictl inspect $CONTAINER_ID | grep -A 20 security_context
# 使用Trivy扫描镜像漏洞
crictl pull docker.io/library/ubuntu:20.04
crictl inspecti docker.io/library/ubuntu:20.04 | grep -A 10 "RepoDigests"
# 使用Trivy扫描镜像
podman run --rm aquasec/trivy image docker.io/library/ubuntu:20.04
# 检查运行时安全
# 使用gVisor运行时
# 在容器配置中指定runtime_handler为runsc
# 检查网络安全
# 使用Cilium网络插件
kubectl apply -f https://raw.githubusercontent.com/cilium/cilium/v1.9/install/kubernetes/quick-install.yaml大师级使用#
CRI-O企业级部署#
企业级CRI-O部署:
# 配置高可用性
# 部署多个CRI-O节点
# 配置负载均衡
# 使用HAProxy负载均衡Kubernetes API服务器
# 配置存储
# 使用分布式存储作为容器存储后端
# 配置网络
# 使用Calico或Cilium作为Kubernetes网络插件
# 部署应用
# 使用Kubernetes部署应用
kubectl apply -f deployment.yaml
# 配置监控
# 使用Prometheus和Grafana监控CRI-O和Kubernetes
# 配置日志
# 使用ELK Stack收集和分析日志
# 配置安全
# 使用Pod Security Policies或Pod Security Standards
kubectl apply -f psp.yamlCRI-O与Knative集成#
将CRI-O与Knative集成:
# 安装Knative
kubectl apply -f https://github.com/knative/serving/releases/download/v0.22.0/serving-crds.yaml
kubectl apply -f https://github.com/knative/serving/releases/download/v0.22.0/serving-core.yaml
# 安装Knative网络插件
kubectl apply -f https://github.com/knative/net-istio/releases/download/v0.22.0/net-istio.yaml
# 部署Serverless应用
cat > service.yaml <<EOF
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
name: hello-world
spec:
template:
spec:
containers:
- image: gcr.io/knative-samples/helloworld-go
env:
- name: TARGET
value: "World"
EOF
kubectl apply -f service.yaml
# 查看应用状态
kubectl get ksvcCRI-O性能调优#
调优CRI-O性能:
# 编辑CRI-O配置
vim /etc/crio/crio.conf
# 调优运行时
[crio.runtime]
runtime_path = "/usr/bin/runc"
runtime_root = "/run/runc"
runtime_engine = "runc"
runtime_mode = "oci"
runtime_request_timeout = "30s"
runtime_servers = [
{
"address": "/var/run/crio/crio.sock",
"stream_address": "",
"stream_port": "",
"runtime": "runc",
"runtime_root": "/run/runc",
"runtime_path": "/usr/bin/runc",
"runtime_engine": "",
"runtime_mode": "oci",
"extensions": [],
"allowed_annotations": [],
"allowed_devices": [],
"allowed_untrusted_artifacts": [],
"default_mounts": [],
"no_pivot": false,
"sandbox_image": "k8s.gcr.io/pause:3.2"
}
]
# 调优存储
[crio.storage]
storage_driver = "overlay2"
storage_option = [
"overlay2.override_kernel_check=true",
"overlay2.size=10G",
"overlay2.metacopy=on"
]
# 调优网络
[crio.network]
network_dir = "/etc/cni/net.d"
plugin_dirs = ["/opt/cni/bin"]
# 重启CRI-O服务
systemctl restart crio
# 重启kubelet服务
systemctl restart kubelet实战案例#
案例一:部署微服务应用#
场景:部署一个基于Spring Boot的微服务应用。
解决方案:使用CRI-O和Kubernetes部署微服务应用。
实施步骤:
构建镜像:
# 使用buildkit构建镜像 buildctl build --frontend=dockerfile.v0 --local context=. --local dockerfile=. --output type=image,name=myapp:latest # 推送镜像到仓库 crictl pull myapp:latest创建Kubernetes部署:
# deployment.yaml apiVersion: apps/v1 kind: Deployment metadata: name: myapp spec: replicas: 3 selector: matchLabels: app: myapp template: metadata: labels: app: myapp spec: containers: - name: myapp image: myapp:latest ports: - containerPort: 8080部署应用:
kubectl apply -f deployment.yaml kubectl apply -f service.yaml # 查看应用状态 kubectl get pods kubectl get svc
结果:
- 成功构建了Spring Boot应用的镜像
- 部署了高可用的微服务应用
- 应用可以通过Service访问
案例二:CRI-O安全加固#
场景:加固CRI-O容器安全。
解决方案:配置CRI-O安全选项。
实施步骤:
- 配置CRI-O安全选项:
# 编辑/etc/crio/crio.conf [crio.runtime]
runtime_path = “/usr/bin/runc” runtime_root = “/run/runc” runtime_engine = “runc” runtime_mode = “oci”
配置默认安全上下文#
[crio.runtime.default] security_context = { “namespace_options”: { “network_namespace”: “”, “pid_namespace”: “”, “ipc_namespace”: “”, “mount_namespace”: “”, “user_namespace”: "" }, “capabilities”: { “add”: [], “drop”: [“ALL”] }, “selinux_options”: { “user”: “”, “role”: “”, “type”: “”, “level”: "" } }
2. **使用gVisor运行时**:
```bash
# 安装gVisor
curl -fsSL https://gvisor.dev/archive/master/latest/x86_64/releases/runsc | sudo tee /usr/local/bin/runsc > /dev/null
sudo chmod +x /usr/local/bin/runsc
# 配置gVisor运行时
[crio.runtime.runtimes.runsc]
runtime_path = "/usr/local/bin/runsc"
runtime_type = "oci"
runtime_engine = ""
runtime_root = "/run/runsc"- 重启CRI-O服务:
systemctl restart crio
结果:
- 成功配置了CRI-O安全选项
- 使用了gVisor运行时提高安全性
- 容器运行在更安全的环境中
案例三:CRI-O性能优化#
场景:优化CRI-O性能。
解决方案:配置CRI-O性能选项。
实施步骤:
- 配置CRI-O性能选项:
# 编辑/etc/crio/crio.conf [crio.runtime]
runtime_path = “/usr/bin/runc” runtime_root = “/run/runc” runtime_engine = “runc” runtime_mode = “oci” runtime_request_timeout = “30s”
配置存储#
[crio.storage] storage_driver = “overlay2” storage_option = [ “overlay2.override_kernel_check=true”, “overlay2.size=10G”, “overlay2.metacopy=on” ]
配置网络#
[crio.network] network_dir = “/etc/cni/net.d” plugin_dirs = ["/opt/cni/bin"]
2. **使用更快的存储后端**:
```bash
# 使用zfs作为存储后端
apt install zfsutils-linux
# 配置zfs存储后端
[crio.storage]
storage_driver = "zfs"
storage_option = [
"zfs.fsname=zpool/crio"
]- 重启CRI-O服务:
systemctl restart crio systemctl restart kubelet
结果:
- 成功优化了CRI-O性能
- 提高了容器启动速度和运行效率
- 减少了资源使用
总结#
CRI-O是一种轻量级、安全、高性能的容器运行时,专为Kubernetes设计。通过本教程的学习,您已经掌握了从入门到大师级的CRI-O使用技术。
主要技术回顾#
- 基础操作:CRI-O的基本命令和操作
- 镜像管理:拉取、推送、构建镜像
- 容器管理:创建、启动、停止容器
- Pod管理:创建和管理Pod sandbox
- 存储管理:配置存储后端
- 网络管理:配置CNI网络
- 运行时管理:配置不同的容器运行时
- 高级功能:集群管理、监控、安全加固
- 企业级应用:高可用性、负载均衡、性能优化
最佳实践#
- 使用最新版本:定期更新CRI-O版本,获取最新的安全补丁和功能
- 配置合理:根据实际需求配置CRI-O,避免过度配置
- 安全加固:使用非特权容器,配置适当的capabilities,使用gVisor等安全运行时
- 性能优化:根据硬件环境优化CRI-O配置,提高性能
- 监控容器:使用Prometheus等工具监控CRI-O状态
- 自动化部署:与CI/CD集成,实现自动化构建、测试和部署
- 备份策略:制定容器数据备份策略,确保数据安全
- 灾难恢复:建立容器环境的灾难恢复计划,应对突发情况
注意事项#
- 版本兼容性:确保CRI-O版本与Kubernetes版本兼容
- 资源管理:合理配置容器资源限制,避免资源争用
- 网络配置:合理配置网络,确保容器间通信安全
- 存储管理:定期清理未使用的镜像、容器和内容,释放存储空间
- 安全审计:定期进行CRI-O安全审计,发现和修复安全问题
- 故障排查:熟悉CRI-O日志和监控,快速排查问题
通过合理学习和使用CRI-O,您可以获得更高效、更安全的容器运行环境。CRI-O作为专为Kubernetes设计的容器运行时,已经被广泛应用于生产环境,掌握CRI-O技术将为您的职业发展带来更多机会。