前言:
在kubernetes集群中,pod依据它的运行方式分为静态pod和动态pod。
静态pod的定义如下:静态pod 是由 kubelet 管理的只在特定node上存在的pod;静态pod总是由kubelet创建的,并且只在kubelet所在的Node上运行。
以上概念说的还是比较抽象,难以理解。说人话就是,静态pod这一类型的pod是由kubelet负责管理的,而kubelet是kubernetes集群的核心组件,此组件可运行在master上也可以运行在工作节点上,一个节点有一个kubelet实例,那么,如果部署的pod类型是静态的,此pod是不需要设置任何亲和的。
常见的静态pod通常是kubeadm部署的kube-controller-manager kube-scheduler kube-apiserver 这些pod,例如minikube部署的集群2 3 4 7都是静态pod:
[root@node3 kubernetes]# kubectl get po -n kube-system -owide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES coredns-7ff77c879f-nsj95 1/1 Running 6 3d2h 10.244.0.18 node3 <none> <none> etcd-node3 1/1 Running 6 3d2h 192.168.217.23 node3 <none> <none> kube-apiserver-node3 1/1 Running 6 3d2h 192.168.217.23 node3 <none> <none> kube-controller-manager-node3 1/1 Running 6 3d2h 192.168.217.23 node3 <none> <none> kube-flannel-ds-amd64-6cdl5 1/1 Running 7 3d2h 192.168.217.23 node3 <none> <none> kube-proxy-vdhzr 1/1 Running 6 3d2h 192.168.217.23 node3 <none> <none> kube-scheduler-node3 1/1 Running 6 3d2h 192.168.217.23 node3 <none> <none> storage-provisioner 1/1 Running 10 3d2h 192.168.217.23 node3 <none> <none>
以上静态pod我们可以观察出一个特点:命名为服务名+主机名,网络模式通常设定的都是hostnetwork,而这样的pod就像是一个稳定的服务,和StateFulSet是比较像的。
那么,下面将仿照这些构成核心组件的静态pod,部署一个像在本地运行的MySQL服务。
一,
静态pod的文件管理设定
静态pod的部署清单文件存放位置为kubelet设定的启动参数--pod-manifest-path此参数的值,而二进制部署的通常是没有设定此参数的,下面以minikube为例,它的静态pod存放路径为/etc/kubernetes/manifests:
[root@node3 manifests]# systemctl status kubelet -l ● kubelet.service - kubelet: The Kubernetes Node Agent Loaded: loaded (/usr/lib/systemd/system/kubelet.service; enabled; vendor preset: disabled) Drop-In: /etc/systemd/system/kubelet.service.d └─10-kubeadm.conf Active: active (running) since Sun 2022-11-06 16:43:38 CST; 3h 18min ago Docs: http://kubernetes.io/docs/ Main PID: 1104 (kubelet) Memory: 80.0M CGroup: /system.slice/kubelet.service └─1104 /var/lib/minikube/binaries/v1.18.8/kubelet --authorization-mode=Webhook --bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --cgroup-driver=systemd --client-ca-file=/var/lib/minikube/certs/ca.crt --config=/var/lib/kubelet/config.yaml --container-runtime=docker --hostname-override=node3 --kubeconfig=/etc/kubernetes/kubelet.conf --network-plugin=cni --node-ip=192.168.217.23 --pod-cidr=10.244.0.0/16 --pod-infra-container-image=registry.aliyuncs.com/google_containers/pause:3.2 --pod-manifest-path=/etc/kubernetes/manifests
那么,如果不想使用这个默认目录,自己定义的话,可以更改此文件的静态pod部署清单存放路径:
[root@node3 manifests]# cat /etc/systemd/system/kubelet.service.d/10-kubeadm.conf [Unit] Wants=docker.socket [Service] ExecStart= ExecStart=/var/lib/minikube/binaries/v1.18.8/kubelet --authorization-mode=Webhook --bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --cgroup-driver=systemd --client-ca-file=/var/lib/minikube/certs/ca.crt --config=/var/lib/kubelet/config.yaml --container-runtime=docker --hostname-override=node3 --kubeconfig=/etc/kubernetes/kubelet.conf --network-plugin=cni --node-ip=192.168.217.23 --pod-cidr=10.244.0.0/16 --pod-infra-container-image=registry.aliyuncs.com/google_containers/pause:3.2 --pod-manifest-path=/etc/kubernetes/manifests
二进制部署的集群,静态pod的资源清单文件存放路径:
[root@k8s-master ~]# systemctl status kubelet -l ● kubelet.service - Kubernetes Kubelet Loaded: loaded (/usr/lib/systemd/system/kubelet.service; enabled; vendor preset: disabled) Active: active (running) since Sun 2022-11-06 20:06:21 CST; 2min 59s ago Main PID: 1303 (kubelet) Memory: 187.9M CGroup: /system.slice/kubelet.service ├─1303 /opt/kubernetes/bin/kubelet --logtostderr=false --v=2 --log-dir=/opt/kubernetes/logs --hostname-override=k8s-master --network-plugin=cni --kubeconfig=/opt/kubernetes/cfg/kubelet.kubeconfig --bootstrap-kubeconfig=/opt/kubernetes/cfg/bootstrap.kubeconfig --config=/opt/kubernetes/cfg/kubelet-config.yml --cert-dir=/opt/kubernetes/ssl --pod-manifest-path=/opt/staticpod/ --pod-infra-container-image=registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.2 ├─3692 /opt/cni/bin/calico └─3821 /opt/cni/bin/calico
[root@k8s-master cfg]# cat kubelet.conf KUBELET_OPTS="--logtostderr=false \ --v=2 \ --log-dir=/opt/kubernetes/logs \ --hostname-override=k8s-master \ --network-plugin=cni \ --kubeconfig=/opt/kubernetes/cfg/kubelet.kubeconfig \ --bootstrap-kubeconfig=/opt/kubernetes/cfg/bootstrap.kubeconfig \ --config=/opt/kubernetes/cfg/kubelet-config.yml \ --cert-dir=/opt/kubernetes/ssl \ --pod-manifest-path=/opt/staticpod/ \ --pod-infra-container-image=registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.2"
根据部署手法不同,此二进制部署的kubelet的配置文件定义在/usr/lib/systemd/system/kubelet.service里指定的kubelet.conf 文件,在此配置文件添加--pod-manifest-path这个启动参数即可。参数设定后,重启kubelet服务即可,此时的--pod-manifest-path指定的路径里放置要部署的静态pod的文件,kubelet即可自动检测文件是否可执行,并进行部署。这里多说一句,此路径非常像linux系统的/etc/init.d/目录,在这个目录下的所有可执行的shell脚本都会开机启动运行,同样的,在上例 的 /opt/staticpod 这个目录下的所有pod类型的可以正常部署的文件都会由kubelet进行部署。
二,
静态pod的局限性:
上面一节讲了存放pod部署文件的路径问题,那么,此路径下是否可以放置任何需要部署的文件内?答案是否定的,不可以,kubelet只能部署kind类型是pod的pod,因此,deployment,statesetful,rc,rs等等所有带有控制器的类型都不可以,如果你非要把这个文件扔进去,那也无所谓,只是kubelet会不停的报警而已。
其次就是安全方面的问题了,如果有不怀好意的人造访了你的服务器,并且将一个恶意的pod部署文件放到上述的路径下了,那么,将会有非常不好的事情发生,或者不怀好意的人进入了你的静态pod文件存放路径,并且非常不巧的是kubeadm部署的集群,那么,所有的核心组件都可能被修改,其危害程度应该是和SQL注入一样的,甚至更危险。因此,对于静态pod的保护需要更多的手段和方法。
静态pod的优势:
简单方便快捷,只要目录内符合条件的部署文件都会自动部署,对此文件的任何修改也会立刻反应到pod中,非常适合那些需要稳定的服务,比如,MySQL数据库,当然,部署文件编写不需要任何的亲和反亲和等等规则,你放置到哪个节点的kubelet的静态pod目录下,它就会在当前节点生成了嘛。
三,
部署静态的MySQL示例
部署一个可在集群外访问的MySQL数据库
这种部署方式由于使用了hostNetwork模式,因此,不需要特别部署service,其中使用了存活探针--持续监测容器的3311端口,此端口是下面的配置文件定义。
使用了hostpath挂载的方式挂载容器的数据库到宿主机的 /opt/mysql/data目录下,配置文件存放路径为 /opt/mysql/conf 。
设置了priorityClassName: system-cluster-critical 最高的调度优先级,防止此pod被其它pod抢占(配合此设置,部署到了kube-system命名空间内)。
设置了MySQL的root密码为123456
将此文件放入静态pod存放路径,即可自动部署,以minikube为例,存放到/etc/kubernetes/manifests目录下即可。
cat > static-mysq.yaml <<EOF apiVersion: v1 kind: Pod metadata: name: mysql labels: run: mysql name: mysql namespace: kube-system spec: containers: - env: - name: MYSQL_ROOT_PASSWORD value: 123456 image: mysql:5.7.39 imagePullPolicy: IfNotPresent livenessProbe: tcpSocket: port: 3311 initialDelaySeconds: 15 periodSeconds: 5 failureThreshold: 8 resources: requests: cpu: 200m name: mysql volumeMounts: - mountPath: /var/lib/mysql name: mysql-data readOnly: false - mountPath: /etc/mysql/mysql.conf.d name: mysql-conf readOnly: false dnsPolicy: ClusterFirst restartPolicy: Always volumes: - name: mysql-data hostPath: path: /opt/mysql/data type: DirectoryOrCreate - name: mysql-conf hostPath: path: /opt/mysql/conf type: DirectoryOrCreate hostNetwork: true priorityClassName: system-cluster-critical status: {} EOF
在启动pod的时候,写入配置文件:
这个配置文件设定了MySQL的服务端口是3311,此端口也是pod的存活探针端口。
设定了慢查询以及binlog日志
cat >/opt/mysql/conf/mysqld.cnf <<EOF [client] default-character-set = utf8mb4 port = 3311 socket = /var/lib/mysql/mysql.sock [mysql] no_auto_rehash show-warnings default-character-set = utf8mb4 socket = /var/lib/mysql/mysql.sock [mysqld] user = mysql port = 3311 symbolic-links = 0 server_id = 56102 datadir = /var/lib/mysql socket = /var/lib/mysql/mysql.sock character-set-server = utf8mb4 skip_name_resolve = 1 lock_wait_timeout = 3600 open_files_limit = 65535 back_log = 1024 max_connections = 512 max_connect_errors = 1000000 table_open_cache = 1024 table_definition_cache = 1024 thread_stack = 512K sort_buffer_size = 4M join_buffer_size = 4M read_buffer_size = 8M read_rnd_buffer_size = 4M bulk_insert_buffer_size = 64M thread_cache_size = 768 interactive_timeout = 600 wait_timeout = 600 tmp_table_size = 32M max_heap_table_size = 32M log_error = /var/lib/mysql/error.log log_error_verbosity = 3 slow_query_log = 1 slow_query_log_file = /var/lib/mysql/slow.log long_query_time = 0.1 log_queries_not_using_indexes = 1 log_throttle_queries_not_using_indexes = 60 min_examined_row_limit = 100 log_slow_admin_statements = 1 log_slow_slave_statements = 1 log_bin = /var/lib/mysql/mysql_binlog binlog_format = ROW sync_binlog = 1 binlog_cache_size = 4M max_binlog_cache_size = 2G max_binlog_size = 1G binlog_rows_query_log_events = 1 binlog_checksum = CRC32 gtid_mode = ON enforce_gtid_consistency = TRUE key_buffer_size = 32M myisam_sort_buffer_size = 128M transaction_isolation = REPEATABLE-READ innodb_buffer_pool_size = 500M innodb_buffer_pool_instances = 4 innodb_data_file_path = ibdata1:12M:autoextend innodb_flush_log_at_trx_commit = 1 innodb_log_buffer_size = 32M innodb_log_file_size = 200M innodb_log_files_in_group = 3 innodb_max_undo_log_size = 1G innodb_io_capacity = 400 innodb_io_capacity_max = 800 innodb_open_files = 65535 innodb_flush_method = O_DIRECT innodb_lru_scan_depth = 4000 innodb_lock_wait_timeout = 10 innodb_rollback_on_timeout = 1 innodb_print_all_deadlocks = 1 innodb_online_alter_log_max_size = 4G innodb_status_file = 1 innodb_status_output = 0 innodb_status_output_locks = 1 innodb_sort_buffer_size = 67108864 innodb_adaptive_hash_index = OFF [mysqldump] quick EOF
Navicat连接MySQL的测试:
可以看到静态pod已经正常运行:
[root@node3 manifests]# kubectl get po -A NAMESPACE NAME READY STATUS RESTARTS AGE default static-web-node3 1/1 Running 6 3d3h kube-system coredns-7ff77c879f-nsj95 1/1 Running 6 3d4h kube-system etcd-node3 1/1 Running 6 3d4h kube-system kube-apiserver-node3 1/1 Running 6 3d4h kube-system kube-controller-manager-node3 1/1 Running 6 3d4h kube-system kube-flannel-ds-amd64-6cdl5 1/1 Running 7 3d4h kube-system kube-proxy-vdhzr 1/1 Running 6 3d4h kube-system kube-scheduler-node3 1/1 Running 6 3d4h kube-system mysql-node3 1/1 Running 0 10m
总结:
静态pod是一个双刃剑的事情,因此需要注意安全,防止类似SQL注入的事情发生,在平常巡检工作中可能还是需要对静态pod的目录予以关注,以上的MySQL数据库部署其实也给我们提供了一个方向:可以利用静态pod组织一个比较稳定可靠的集群,这样的集群部署会比其它方式更简单快速。