CRI-O的诞生
开源界已经转向open containers 已有一段时间了。无论是在Kubernetes还是更低层中,容器标准都在各个层面孕育了创新生态系统。
一切始于2015年6月成立“ Open Containers Initiative”。这项早期工作标准化了容器映像和运行时规范。这些保证了工具可以针对容器映像以及如何运行它们以单一格式进行标准化。后来,添加了分发规范,允许各地的用户*共享容器映像。
接下来,Kubernetes社区在Container Runtime Interface (CRI).的可插拔接口上进行了标准化。这使Kubernetes用户可以插入除Docker之外的其他容器引擎。
来自Red Hat和Google的工程师认识到市场对容器引擎的需求,该容器引擎可以通过CRI协议接受来自Kubelet的请求,并启动符合上述OCI规范的容器。CRI-O诞生了。
CRI-O和CoreOS的创新
使用OpenShift 4时,默认容器引擎已从Docker迁移到CRI-O,从而提供了精简,稳定的容器运行时,该运行时与Kubernetes步调一致。这极大地简化了集群的支持和配置。作为OpenShift 4的一部分,容器引擎和主机的所有配置和管理都将自动化。
使用OpenShift 4,无需登录到各个容器主机并安装容器引擎、配置存储、配置注册表服务器以进行搜索或配置网络。Kubernetes始终使用户能够通过定义所需的状态并使用Controller来确保实际状态与定义的状态尽可能匹配,从而管理应用程序。这种定义的状态,实际状态方法对于开发人员和操作人员都是强大的。开发人员可以定义所需的状态,然后将其作为YAML或JSON文件交给操作员,然后操作员可以使用完全相同的定义实例化生产环境中的应用程序。
通过在平台中使用Operators,OpenShift 4为管理RHEL CoreOS和CRI-O带来了定义的状态,实际状态范例。操作系统和容器引擎的配置和版本控制任务由 Machine Config Operator(MCO)自动执行。MCO通过以全自动方式处理安装的最后一英里以及Day2的操作,极大地简化了集群管理员的工作。这使OpenShift 4成为真正的云平台。稍后再详细介绍。
运行容器
自版本3.7起,用户可以选择在OpenShift中使用CRI-O(作为技术预览版),而从版本3.9(通常)(受支持)开始使用。从3.10版开始,红帽还一直在OpenShift Online中针对生产工作负载运行CRI-O。这为CRI-O团队提供了在大型Kubernetes集群中大规模运行容器的丰富经验。要了解Kubernetes如何使用CRI-O的基本概念,请看以下架构图:
CRI-O通过在供应新节点以及发布新版本的OpenShift时保持整个顶层处于锁定状态,从而简化了新容器主机的制造。一起修订整个平台可以进行事务更新/回滚,还可以防止容器主机内核,容器引擎,Kubelet和Kubernetes Master之间的依赖关系出现死锁。当平台的所有组件都一起受版本控制时,从A点到B点总会有一条清晰的路径。这将导致更轻松的更新,更好的安全性,更好的性能责任制以及更少的升级和新版本成本。
如前所述,利用Machine Config Operator在OpenShift 4中管理容器主机和容器引擎可以实现Kubernetes前所未有的更高水平的自动化水平。为了演示,让我们展示如何将更改部署到crio.conf文件。不要迷失术语,只专注于结果。
为了演示,让我们创建一个所谓的容器运行时配置。可以将其视为代表CRI-O的配置的Kubernetes资源。实际上,它是MachineConfig的专用版本,它表示在OpenShift集群中部署到RHEL CoreOS计算机的任何配置。
已经实现了称为ContainerRuntimeConfig的自定义资源,以使集群管理员可以轻松调整CRI-O。它甚至功能强大到可以仅根据所谓的MachineConfigPool将其应用于某些节点。可以将这视为一组功能相同的机器。
首先,CRIO的配置文件在OCP节点的/etc/crio/crio.conf中。OCP4的Master和Worker节点默认使用CoreOS,这是不可变基础架构。因此,我们如果想改这个配置文件的内容,通过CRD的方式修改即可。我们查看这个配置文件中的配置内容:
[root@master-0 ~]# cat /etc/crio/crio.conf |grep -v "#" | sed '/^$/d'
[crio]
log_dir = "/var/log/crio/pods"
version_file = "/var/run/crio/version"
version_file_persist = "/var/lib/crio/version"
[crio.api]
listen = "/var/run/crio/crio.sock"
host_ip = ""
stream_address = ""
stream_port = "10010"
stream_enable_tls = false
stream_tls_cert = ""
stream_tls_key = ""
stream_tls_ca = ""
grpc_max_send_msg_size = 16777216
grpc_max_recv_msg_size = 16777216
[crio.runtime]
default_runtime = "runc"
no_pivot = false
conmon = "/usr/libexec/crio/conmon"
conmon_cgroup = "pod"
conmon_env = [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
]
default_env = [
"NSS_SDB_USE_CACHE=no",
]
selinux = true
seccomp_profile = ""
apparmor_profile = "crio-default"
cgroup_manager = "systemd"
default_capabilities = [
"CHOWN",
"DAC_OVERRIDE",
"FSETID",
"FOWNER",
"NET_RAW",
"SETGID",
"SETUID",
"SETPCAP",
"NET_BIND_SERVICE",
"SYS_CHROOT",
"KILL",
]
default_sysctls = [
]
additional_devices = [
]
hooks_dir = [
"/etc/containers/oci/hooks.d",
]
default_mounts = [
]
pids_limit = 1024
log_size_max = -1
log_to_journald = false
container_exits_dir = "/var/run/crio/exits"
container_attach_socket_dir = "/var/run/crio"
bind_mount_prefix = ""
read_only = false
log_level = "info"
uid_mappings = ""
gid_mappings = ""
ctr_stop_timeout = 0
manage_network_ns_lifecycle = false
[crio.runtime.runtimes.runc]
runtime_path = ""
runtime_type = "oci"
runtime_root = "/run/runc"
[crio.image]
default_transport = "docker://"
global_auth_file = "/var/lib/kubelet/config.json"
pause_image = "quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:1428f0d9146362d35d6bced979aca00a669ef89903014b0764b5191c18da5ff0"
pause_image_auth_file = "/var/lib/kubelet/config.json"
pause_command = "/usr/bin/pod"
signature_policy = ""
image_volumes = "mkdir"
[crio.network]
network_dir = "/etc/kubernetes/cni/net.d/"
plugin_dirs = [
"/var/lib/cni/bin",
]
[crio.metrics]
enable_metrics = true
metrics_port = 9537
我们通过crd的方式,在K8S层面修改配置中的pidsLimit(初始为1024)和logLevel(初始为info):
[root@master-0 ~]# cat /etc/crio/crio.conf |grep -v "#" | sed '/^$/d' |grep -i log
log_level = "info"
[root@master-0 ~]# cat /etc/crio/crio.conf |grep -v "#" | sed '/^$/d' |grep -i pids
pids_limit = 1024
vi ContainerRuntimeConfig.yaml
apiVersion: machineconfiguration.openshift.io/v1
kind: ContainerRuntimeConfig
metadata:
name: set-log-and-pid
spec:
machineConfigPoolSelector:
matchLabels:
debug-crio: config-log-and-pid
containerRuntimeConfig:
pidsLimit: 2048
logLevel: debug
现在,将其提交给Kubernetes集群并验证它是否已创建。注意,它看起来与任何其他Kubernetes资源一样:
oc create -f ContainerRuntimeConfig.yaml
oc get ContainerRuntimeConfig
NAME AGE
set-log-and-pid 22h
创建ContainerRuntimeConfig之后,我们必须修改其中一个MachineConfigPool,以告诉Kubernetes我们希望将
此配置应用于集群中的特定计算机组。在这种情况下,我们将为Master修改MachineConfigPool:
oc edit MachineConfigPool/master
...
metadata:
creationTimestamp: 2019-04-10T23:42:28Z
generation: 1
labels:
debug-crio: config-log-and-pid
operator.machineconfiguration.openshift.io/required-for-upgrade: ""
加在这个位置:
此时,MCO开始为群集制造一个新的crio.conf文件。
ContainerRuntimeConfig只是MachineConfig的专用版本,因此我们可以通过查看呈现的MachineConfigs
来查看输出:
oc get MachineConfigs | grep rendered
rendered-master-c923f24f01a0e38c77a05acfd631910b 4.0.22-201904011459-dirty 2.2.0 16h
rendered-master-f722b027a98ac5b8e0b41d71e992f626 4.0.22-201904011459-dirty 2.2.0 4m
rendered-worker-9777325797fe7e74c3f2dd11d359bc62 4.0.22-201904011459-dirty 2.2.0 16h
我们可以查看一个Wroker节点最多运行容器的适量:
python3 -c "import sys, urllib.parse; print(urllib.parse.unquote(sys.argv[1]))" $(oc get MachineConfig/rendered-master-f722b027a98ac5b8e0b41d71e992f626 -o YAML | grep -B4 crio.conf | grep source | tail -n 1 | cut -d, -f2) | grep pid
pids_limit = 2048
现在,验证它是否已部署到主节点。首先,获取集群中节点的列表:
oc get node | grep master
Output:
ip-10-0-135-153.us-east-2.compute.internal Ready master 23h v1.12.4+509916ce1
ip-10-0-154-0.us-east-2.compute.internal Ready master 23h v1.12.4+509916ce1
ip-10-0-166-79.us-east-2.compute.internal Ready master 23h v1.12.4+509916ce1
检查部署的文件。您会注意到它已使用我们在ContainerRuntimeConfig资源中指定的新pid和debug指令
进行了更新。
oc debug node/ip-10-0-135-153.us-east-2.compute.internal -- cat /host/etc/crio/crio.conf | egrep 'debug||pid’
...
pids_limit = 2048
...
log_level = "debug"
所有这些更改都是在不运行SSH的情况下对群集进行的。一切都是通过与Kuberentes大师沟通来完成的。仅主节点配置有这些新参数。工作节点未更改,证明了已定义状态的值,Kubernetes应用于容器主机和具有可互换零件的容器引擎的实际状态方法。
上面的演示重点介绍了对具有三个工作节点的小型OpenShift Container Platform 4集群或具有3000的大型生产实例进行更改的能力。这两种方法的工作量相同-数量不多-一个ContainerRuntimeConfig文件和一个标签更改到MachineConfigPool。而且,您可以在整个生命周期内使用任何版本的基于OpenShift Container Platform 4.X的Kubernetes。那是强大的。
通常,技术公司的步伐如此之快,以至于我们无法很好地解释为什么我们为基础组件选择技术。容器引擎一直以来都是用户直接与之交互的组件。由于容器的流行合法地从容器引擎开始,因此用户经常会对它们产生个人兴趣。值得一提的是,为什么红帽选择了CRI-O。容器已经发展,现在的重点完全放在业务流程上,我们发现CRI-O可以在OpenShift 4中提供最佳体验。