在安装kubernetes的时候一直出错,经过一番排查之后,发现是因为docker网络代理的问题。
有时因为网络原因,比如公司 NAT,或其它啥的,需要使用代理。Docker
的代理配置,略显复杂,因为有三种场景。但基本原理都是一致的,都是利用 Linux
的 http_proxy
等环境变量。
在执行docker pull
时,是由守护进程dockerd
来执行。因此,代理需要配在dockerd
的环境中。而这个环境,则是受systemd
所管控,因此实际是systemd
的配置。
sudo mkdir -p /etc/systemd/system/docker.service.dsudo touch /etc/systemd/system/docker.service.d/proxy.conf
在这个proxy.conf
文件(可以是任意*.conf
的形式)中,添加以下内容:
[Service]Environment="HTTP_PROXY=http://proxy.example.com:8080/"Environment="HTTPS_PROXY=http://proxy.example.com:8080/"Environment="NO_PROXY=localhost,127.0.0.1,.example.com"
其中,proxy.example.com:8080
要换成可用的免密代理。通常使用 cntlm
在本机自建免密代理,去对接公司的代理。可参考《Linux下安装配置Cntlm 代理》。
在容器运行阶段,如果需要代理上网,则需要配置 ~/.docker/config.json
。以下配置,只在Docker 17.07及以上版本生效。
{ "proxies": { "default": { "httpProxy": "http://proxy.example.com:8080", "httpsProxy": "http://proxy.example.com:8080", "noProxy": "localhost,127.0.0.1,.example.com" } }}
这个是用户级的配置,除了 proxies
,docker login
等相关信息也会在其中。而且还可以配置信息展示的格式、插件参数等。
此外,容器的网络代理,也可以直接在其运行时通过 -e
注入 http_proxy
等环境变量。这两种方法分别适合不同场景。config.json
非常方便,默认在所有配置修改后启动的容器生效,适合个人开发环境。在CI/CD的自动构建环境、或者实际上线运行的环境中,这种方法就不太合适,用 -e
注入这种显式配置会更好,减轻对构建、部署环境的依赖。当然,在这些环境中,最好用良好的设计避免配置代理上网。
虽然 docker build
的本质,也是启动一个容器,但是环境会略有不同,用户级配置无效。在构建时,需要注入 http_proxy
等参数。
docker build . \ --build-arg "HTTP_PROXY=http://proxy.example.com:8080/" \ --build-arg "HTTPS_PROXY=http://proxy.example.com:8080/" \ --build-arg "NO_PROXY=localhost,127.0.0.1,.example.com" \ -t your/image:tag
注意:无论是 docker run
还是 docker build
,默认是网络隔绝的。如果代理使用的是localhost:3128
这类,则会无效。这类仅限本地的代理,必须加上 --network host
才能正常使用。而一般则需要配置代理的外部IP,而且代理本身要开启 Gateway 模式
sudo dnf groupinstall "Development Tools"sudo dnf install libglvnd-devel elfutils-libelf-develsudo yum install kernel-devel sudo yum -y install epel-releasesudo yum -y install dkms sudo dnf install wget
sudo grub2-editenv - set "$(grub2-editenv - list | grep kernelopts) nouveau.modeset=0"sudo mv /boot/initramfs-$(uname -r).img /boot/initramfs-$(uname -r).img-nouveausudo dracut /boot/initramfs-$(uname -r).img $(uname -r)
wget https://us.download.nvidia.cn/XFree86/Linux-x86_64/440.82/NVIDIA-Linux-x86_64-440.82.run
kernel-source-path 换成自己的
sudo ./NVIDIA-Linux-x86_64-440.82.run --kernel-source-path=/usr/src/kernels/4.18.0-193.6.3.el8_2.x86_64
nvidia-smi
先上一张配置成功截图:
centos8默认安装了podman容器,它和docker可能有冲突需要卸载掉
sudo yum remove podman
sudo swapoff -a
sudo sed -i 's/.*swap.*/#&/' /etc/fstab
setenforce 0
sudo sed -i "s/^SELINUX=enforcing/SELINUX=disabled/g" /etc/selinux/config
sudo systemctl stop firewalld.servicesudo systemctl disable firewalld.service
sudo curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-8.repo
将如下内容保存到:/etc/yum.repos.d/kubernetes.repo
[kubernetes]name=Kubernetesbaseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/enabled=1gpgcheck=1repo_gpgcheck=1gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
由于目前阿里镜像中还没有CentOS8的kubernetes,但是可以使用CentOS7的安装包,所以上面是使用的kubernetes-el7-x86_64,如果有CentOS8的,则为kubernetes-el8-x86_64。
sudo yum install -y yum-utils device-mapper-persistent-data lvm2 net-toolssudo yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repoyum -y install docker-ce
如果出现错误:
(base) [root@localhost tmp]# yum -y install docker-ceRepository AppStream is listed more than once in the configurationRepository extras is listed more than once in the configurationRepository PowerTools is listed more than once in the configurationRepository centosplus is listed more than once in the configuration上次元数据过期检查:0:00:35 前,执行于 2021年04月01日 星期四 14时28分07秒。错误: 问题: package docker-ce-3:20.10.5-3.el8.x86_64 requires containerd.io >= 1.4.1, but none of the providers can be installed - package containerd.io-1.4.3-3.1.el8.x86_64 conflicts with runc provided by runc-1.0.0-70.rc92.module_el8.3.0+699+d61d9c41.x86_64 - package containerd.io-1.4.3-3.1.el8.x86_64 obsoletes runc provided by runc-1.0.0-70.rc92.module_el8.3.0+699+d61d9c41.x86_64 - package containerd.io-1.4.3-3.2.el8.x86_64 conflicts with runc provided by runc-1.0.0-70.rc92.module_el8.3.0+699+d61d9c41.x86_64 - package containerd.io-1.4.3-3.2.el8.x86_64 obsoletes runc provided by runc-1.0.0-70.rc92.module_el8.3.0+699+d61d9c41.x86_64 - package containerd.io-1.4.4-3.1.el8.x86_64 conflicts with runc provided by runc-1.0.0-70.rc92.module_el8.3.0+699+d61d9c41.x86_64 - package containerd.io-1.4.4-3.1.el8.x86_64 obsoletes runc provided by runc-1.0.0-70.rc92.module_el8.3.0+699+d61d9c41.x86_64 - problem with installed package buildah-1.11.6-7.module_el8.2.0+305+5e198a41.x86_64 - package buildah-1.11.6-7.module_el8.2.0+305+5e198a41.x86_64 requires runc >= 1.0.0-26, but none of the providers can be installed - package buildah-1.16.7-4.module_el8.3.0+699+d61d9c41.x86_64 requires runc >= 1.0.0-26, but none of the providers can be installed - package containerd.io-1.4.3-3.1.el8.x86_64 conflicts with runc provided by runc-1.0.0-65.rc10.module_el8.2.0+305+5e198a41.x86_64 - package containerd.io-1.4.3-3.1.el8.x86_64 obsoletes runc provided by runc-1.0.0-65.rc10.module_el8.2.0+305+5e198a41.x86_64 - package containerd.io-1.4.3-3.2.el8.x86_64 conflicts with runc provided by runc-1.0.0-65.rc10.module_el8.2.0+305+5e198a41.x86_64 - package containerd.io-1.4.3-3.2.el8.x86_64 obsoletes runc provided by runc-1.0.0-65.rc10.module_el8.2.0+305+5e198a41.x86_64 - package containerd.io-1.4.4-3.1.el8.x86_64 conflicts with runc provided by runc-1.0.0-65.rc10.module_el8.2.0+305+5e198a41.x86_64 - package containerd.io-1.4.4-3.1.el8.x86_64 obsoletes runc provided by runc-1.0.0-65.rc10.module_el8.2.0+305+5e198a41.x86_64 - cannot install the best candidate for the job - package runc-1.0.0-56.rc5.dev.git2abd837.module_el8.3.0+569+1bada2e4.x86_64 is filtered out by modular filtering - package runc-1.0.0-64.rc10.module_el8.3.0+479+69e2ae26.x86_64 is filtered out by modular filtering(尝试在命令行中添加 '--allowerasing' 来替换冲突的软件包 或 '--skip-broken' 来跳过无法安装的软件包 或 '--nobest' 来不只使用最佳选择的软件包)
可以通过如下方式来解决:
yum -y install docker-ce --allowerasing
为了docker加速pull,可以设置镜像加速:
sudo mkdir -p /etc/dockersudo vim /etc/docker/daemon.json
设置为如下内容:
{ "registry-mirrors": ["https://docker.mirrors.ustc.edu.cn"]}
安装kubectl、kubelet、kubeadm,设置kubelet开机启动,启动kubelet。
sudo yum install -y kubectl kubelet kubeadmsudo systemctl enable kubeletsudo systemctl start kubelet
查看K8S版本
(base) ➜ ~ kubeadm version kubeadm version: &version.Info{Major:"1", Minor:"20", GitVersion:"v1.20.5", GitCommit:"6b1d87acf3c8253c123756b9e61dac642678305f", GitTreeState:"clean", BuildDate:"2021-03-18T01:08:27Z", GoVersion:"go1.15.8", Compiler:"gc", Platform:"linux/amd64"}(base) ➜ ~ kubectl version --clientClient Version: version.Info{Major:"1", Minor:"20", GitVersion:"v1.20.5", GitCommit:"6b1d87acf3c8253c123756b9e61dac642678305f", GitTreeState:"clean", BuildDate:"2021-03-18T01:10:43Z", GoVersion:"go1.15.8", Compiler:"gc", Platform:"linux/amd64"}(base) ➜ ~ kubelet --version Kubernetes v1.20.5
可以看到kubelet的版本为1.20.5。
kubeadm init --apiserver-advertise-address=0.0.0.0 --apiserver-cert-extra-sans=127.0.0.1 --image-repository=registry.aliyuncs.com/google_containers --ignore-preflight-errors=all --kubernetes-version=v1.20.5 --service-cidr=10.10.0.0/16 --pod-network-cidr=10.18.0.0/16
运行后出现问题:
[root@localhost admin]# kubeadm init --apiserver-advertise-address=0.0.0.0 \--apiserver-cert-extra-sans=127.0.0.1 \--image-repository=registry.aliyuncs.com/google_containers \--ignore-preflight-errors=all \--kubernetes-version=v1.20.5 \--service-cidr=10.10.0.0/16 \--pod-network-cidr=10.18.0.0/16W0702 16:23:11.951553 16395 configset.go:202] WARNING: kubeadm cannot validate component configs for API groups [kubelet.config.k8s.io kubeproxy.config.k8s.io][init] Using Kubernetes version: v1.20.5[preflight] Running pre-flight checks [WARNING IsDockerSystemdCheck]: detected "cgroupfs" as the Docker cgroup driver. The recommended driver is "systemd". Please follow the guide at https://kubernetes.io/docs/setup/cri/[preflight] Pulling images required for setting up a Kubernetes cluster[preflight] This might take a minute or two, depending on the speed of your internet connection[preflight] You can also perform this action in beforehand using 'kubeadm config images pull'
查看docker信息:
docker info | grep Cgroup
可以看到驱动为Cgroup,需要改为systemd。
编辑文件/usr/lib/systemd/system/docker.service
在ExecStart命令中添加
--exec-opt native.cgroupdriver=systemd
然后重启docker,再查看信息,可以看到已经变为systemd了
systemctl daemon-reloadsystemctl restart dockerdocker info | grep Cgroup
此时再执行下面的命令进行初始化:
kubeadm init --apiserver-advertise-address=0.0.0.0 \--apiserver-cert-extra-sans=127.0.0.1 \--image-repository=registry.aliyuncs.com/google_containers \--ignore-preflight-errors=all \--kubernetes-version=v1.20.5 \--service-cidr=10.10.0.0/16 \--pod-network-cidr=10.18.0.0/16
由于kubeadm 默认从官网k8s.grc.io下载所需镜像,国内无法访问,因此需要通过–image-repository指定阿里云镜像仓库地址。
[root@localhost admin]# kubeadm init --apiserver-advertise-address=0.0.0.0 --apiserver-cert-extra-sans=127.0.0.1 --image-repository=registry.aliyuncs.com/google_containers --ignore-preflight-errors=all --kubernetes-version=v1.18.2 --service-cidr=10.10.0.0/16 --pod-network-cidr=10.18.0.0/16W0702 17:47:41.592876 62703 configset.go:202] WARNING: kubeadm cannot validate component configs for API groups [kubelet.config.k8s.io kubeproxy.config.k8s.io][init] Using Kubernetes version: v1.20.5[preflight] Running pre-flight checks [WARNING FileAvailable--etc-kubernetes-manifests-kube-apiserver.yaml]: /etc/kubernetes/manifests/kube-apiserver.yaml already exists [WARNING FileAvailable--etc-kubernetes-manifests-kube-controller-manager.yaml]: /etc/kubernetes/manifests/kube-controller-manager.yaml already exists [WARNING FileAvailable--etc-kubernetes-manifests-kube-scheduler.yaml]: /etc/kubernetes/manifests/kube-scheduler.yaml already exists [WARNING FileAvailable--etc-kubernetes-manifests-etcd.yaml]: /etc/kubernetes/manifests/etcd.yaml already exists [WARNING Port-10250]: Port 10250 is in use [WARNING Port-2379]: Port 2379 is in use [WARNING Port-2380]: Port 2380 is in use [WARNING DirAvailable--var-lib-etcd]: /var/lib/etcd is not empty[preflight] Pulling images required for setting up a Kubernetes cluster[preflight] This might take a minute or two, depending on the speed of your internet connection[preflight] You can also perform this action in beforehand using 'kubeadm config images pull'[kubelet-start] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env"[kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"[kubelet-start] Starting the kubelet[certs] Using certificateDir folder "/etc/kubernetes/pki"[certs] Using existing ca certificate authority[certs] Using existing apiserver certificate and key on disk[certs] Using existing apiserver-kubelet-client certificate and key on disk[certs] Using existing front-proxy-ca certificate authority[certs] Using existing front-proxy-client certificate and key on disk[certs] Using existing etcd/ca certificate authority[certs] Using existing etcd/server certificate and key on disk[certs] Using existing etcd/peer certificate and key on disk[certs] Using existing etcd/healthcheck-client certificate and key on disk[certs] Using existing apiserver-etcd-client certificate and key on disk[certs] Using the existing "sa" key[kubeconfig] Using kubeconfig folder "/etc/kubernetes"[kubeconfig] Using existing kubeconfig file: "/etc/kubernetes/admin.conf"[kubeconfig] Using existing kubeconfig file: "/etc/kubernetes/kubelet.conf"[kubeconfig] Using existing kubeconfig file: "/etc/kubernetes/controller-manager.conf"[kubeconfig] Using existing kubeconfig file: "/etc/kubernetes/scheduler.conf"[control-plane] Using manifest folder "/etc/kubernetes/manifests"[control-plane] Creating static Pod manifest for "kube-apiserver"[control-plane] Creating static Pod manifest for "kube-controller-manager"W0702 17:49:34.509168 62703 manifests.go:225] the default kube-apiserver authorization-mode is "Node,RBAC"; using "Node,RBAC"[control-plane] Creating static Pod manifest for "kube-scheduler"W0702 17:49:34.510843 62703 manifests.go:225] the default kube-apiserver authorization-mode is "Node,RBAC"; using "Node,RBAC"[etcd] Creating static Pod manifest for local etcd in "/etc/kubernetes/manifests"[wait-control-plane] Waiting for the kubelet to boot up the control plane as static Pods from directory "/etc/kubernetes/manifests". This can take up to 4m0s[apiclient] All control plane components are healthy after 12.003628 seconds[upload-config] Storing the configuration used in ConfigMap "kubeadm-config" in the "kube-system" Namespace[kubelet] Creating a ConfigMap "kubelet-config-1.18" in namespace kube-system with the configuration for the kubelets in the cluster[upload-certs] Skipping phase. Please see --upload-certs[mark-control-plane] Marking the node localhost.localdomain as control-plane by adding the label "node-role.kubernetes.io/master=''"[mark-control-plane] Marking the node localhost.localdomain as control-plane by adding the taints [node-role.kubernetes.io/master:NoSchedule][bootstrap-token] Using token: l21jwf.pjzezg1xmopqoj0p[bootstrap-token] Configuring bootstrap tokens, cluster-info ConfigMap, RBAC Roles[bootstrap-token] configured RBAC rules to allow Node Bootstrap tokens to get nodes[bootstrap-token] configured RBAC rules to allow Node Bootstrap tokens to post CSRs in order for nodes to get long term certificate credentials[bootstrap-token] configured RBAC rules to allow the csrapprover controller automatically approve CSRs from a Node Bootstrap Token[bootstrap-token] configured RBAC rules to allow certificate rotation for all node client certificates in the cluster[bootstrap-token] Creating the "cluster-info" ConfigMap in the "kube-public" namespace[kubelet-finalize] Updating "/etc/kubernetes/kubelet.conf" to point to a rotatable kubelet client certificate and key[addons] Applied essential addon: CoreDNS[addons] Applied essential addon: kube-proxyYour 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/configYou should now deploy a pod network to the cluster.Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at: https://kubernetes.io/docs/concepts/cluster-administration/addons/Then you can join any number of worker nodes by running the following on each as root:kubeadm join 192.168.1.134:6443 --token l21jwf.pjzezg1xmopqoj0p \ --discovery-token-ca-cert-hash sha256:0b1062f2ec73f8c35c1bfecd857a287b128aba7ae5c0673ea604c9ac7c296a95
执行提示中的命令:
mkdir -p $HOME/.kubesudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/configsudo chown $(id -u):$(id -g) $HOME/.kube/config
再执行:
kubectl get nodekubectl get pod --all-namespaces
node节点为NotReady,因为coredns pod没有启动,缺少网络pod。
kubectl apply -f https://docs.projectcalico.org/manifests/calico.yaml
过一会再查看信息,节点已经处于Ready状态了。
将官方的recommended.yaml文件下载下来。可以使用下面的命令下载,如果国内无法访问https://raw.githubusercontent.com,则可以在前面的链接中复制内容再保存。
wget https://raw.githubusercontent.com/kubernetes/dashboard/master/aio/deploy/recommended.yaml
由于官方没使用nodeport,所以需要修改文件,添加两行配置。
kind: ServiceapiVersion: v1metadata: labels: k8s-app: kubernetes-dashboard name: kubernetes-dashboard namespace: kubernetes-dashboardspec: type: NodePort #添加这行 ports: - port: 443 targetPort: 8443 nodePort: 30000 #添加这行 selector: k8s-app: kubernetes-dashboard
然后创建POD,并查看kubernetes-dashboard
kubectl create -f recommended.yamlkubectl get svc -n kubernetes-dashboard
此时,可以使用浏览器访问:https://192.168.1.134:30000/#/login,其中的IP是本机的IP。
这里有两种登录方式:
kubectl create sa dashboard-admin -n kube-system
kubectl create clusterrolebinding dashboard-admin --clusterrole=cluster-admin --serviceaccount=kube-system:dashboard-admin
ADMIN_SECRET=$(kubectl get secrets -n kube-system | grep dashboard-admin | awk '{print $1}')DASHBOARD_LOGIN_TOKEN=$(kubectl describe secret -n kube-system ${ADMIN_SECRET} | grep -E '^token' | awk '{print $2}')echo ${DASHBOARD_LOGIN_TOKEN}
输入Token后,即可登录成功~需要注意的是Token默认有效期是24小时,过期需要重新生成token。
有了kubernetes-dashboard的帮助,就可以可视化的部署与监控应用了。
kubeadm token list
kubeadm token create
kubeadm token delete TokenXXX
kubeadm token create --print-join-command
或者:
token=$(kubeadm token generate)kubeadm token create $token --print-join-command --ttl=0
]]>自己简单用来同步博客
FreeFileSync 是一款开源的 Windows, Linux 和 macOS 下文件和文件夹同步软件。 它可以比对目录下的文件,然后执行备份操作。它具有简单的多语言操作界面,可以执行本地、双机手动或自动按时备份,并可过滤目录下文件。
下载地址:Download the Latest Version - FreeFileSync
设置云盘ip地址、认证信息及远程目录,如图:
设置比较、过滤器、同步设置:
点击如下红框部分,即可开始比较和同步,如下图:
Cython是具有C数据类型的Python。使用Cython我们可以通过改写部分业务逻辑为C代码并融合到Python中,起到加速代码执行速度的作用。
pip install cython
新建hello_world.pyx
文件,内容如下:
print("Hello World")from libc.math cimport sincpdef double f(double x): return sin(x*x)cdef int c_add(int a, int b): return a + bdef add(a: int, b: int): return c_add(a, b)def sub(a: int, b: int): return a - b
以上有三种定义函数的方式:
示例分别为:
cdef int c_add(int a, int b): return a + bdef add(a: int, b: int): return c_add(a, b)
cpdef double f(double x): return sin(x*x)
def sub(a: int, b: int): return a - b
from distutils.core import setupfrom Cython.Build import cythonizesetup( ext_modules = cythonize("hello_world.pyx", compiler_directives={'language_level' : "3"}))
python setup.py build_ext --inplace
(base) ➜ testCython pwd/root/Projects/CppProjects/testCython(base) ➜ testCython lsbuild hello_world.cpython-38-x86_64-linux-gnu.so setup.pyhello_world.c hello_world.pyx(base) ➜ testCython pythonPython 3.8.3 (default, May 19 2020, 18:47:26) [GCC 7.3.0] :: Anaconda, Inc. on linuxType "help", "copyright", "credits" or "license" for more information.>>> import hello_worldHello World>>> dir(hello_world)['__builtins__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', '__test__', 'add', 'f', 'sub']>>> hello_world.add(3, 4)7>>> hello_world.f(3.3)-0.9944322093031951>>> hello_world.sub(3.4, 5.5)-2.1>>> exit()
pybind11是一个轻量级的头文件库,它在Python中公开c++类型,反之亦然,主要用于创建现有c++代码的Python绑定。
简而言之,pybind11是用于实现Python调用c++代码的相对好用的工具。
git clone https://github.com/pybind/pybind11.git --depth=1
编写example.cpp
文件内容如下:
#include <pybind11/pybind11.h>namespace py = pybind11;int add(int i, int j){ return i + j;}int sub(int i, int j){ return i - j;}int multiply(int i, int j){ return i * j;}PYBIND11_MODULE(example, m){ m.doc() = "pybind11 example plugin"; // 可选的模块说明 m.def("add", &add, "A function which adds two numbers"); m.def("sub", &sub, "A function which subs two numbers"); m.def("multiply", &multiply, "A function which multiplies two numbers");}
CMakeLists.txt
文件编写CMakeLists.txt
文件,内容如下:
cmake_minimum_required(VERSION 3.11)project(learnPybind11)add_subdirectory(pybind11)pybind11_add_module(example example.cpp)
mkdir buildcmake ..make
(base) ➜ learnPybind11 lsbuild CMakeLists.txt example.cpp pybind11(base) ➜ learnPybind11 tree -L 1.├── build├── CMakeLists.txt├── example.cpp└── pybind112 directories, 2 files(base) ➜ learnPybind11 tree -L 2.├── build│ ├── CMakeCache.txt│ ├── CMakeFiles│ ├── cmake_install.cmake│ ├── example.cpython-38-x86_64-linux-gnu.so│ ├── Makefile│ └── pybind11├── CMakeLists.txt├── example.cpp└── pybind11 ├── build ├── CMakeFiles ├── cmake_install.cmake ├── CMakeLists.txt ├── docs ├── include ├── LICENSE ├── Makefile ├── MANIFEST.in ├── pybind11 ├── pyproject.toml ├── README.rst ├── setup.cfg ├── setup.py ├── tests └── tools11 directories, 15 files
(base) ➜ build pwd/root/Projects/CppProjects/learnPybind11/build(base) ➜ build pythonPython 3.8.3 (default, May 19 2020, 18:47:26) [GCC 7.3.0] :: Anaconda, Inc. on linuxType "help", "copyright", "credits" or "license" for more information.>>> import example>>> dir(example)['__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'add', 'multiply', 'sub']>>> example.add(3,4)7>>> exit()
一个基于Python实现的小巧简单的基于模板匹配的自然语言理解框架。
这里的自然语言理解仅指意图识别和词槽提取。
pip install lightnlu
如编写words.yml
文件如下:
- name: person aliases: - 人物 type: json config: path: data/person.json- name: place aliases: - 地点 - 位置 - 城市 - 区域 type: csv config: path: data/place.csv- name: relation aliases: [] type: yml config: path: data/relation.yml- name: predicate aliases: [] type: yml config: path: data/predicate.yml
其中对应的各yml、json、csv文件内容如下:
person.json
中内容如下:
{"name": "曹操", "id": "1"}{"name": "刘备", "id": "2"}{"name": "诸葛亮", "id": "3"}{"name": "曹丕", "id": "4"}{"name": "曹植", "id": "5"}
place.csv
中内容如下:
name,id洛阳,1长安,2新野,3赤壁,4宛城,5
relation.yml
中内容如下:
son: - 儿子father: - 父亲 - 爸爸
predicatel.yml
中内容如下:
is: - 是 - 为isnot: - 不是 - 不为
如编写pattern.yml
文件如下:
- name: father_son_relation patterns: - - [person, ~, son] # 规则为 [类型, id值, 词槽名称] - [relation, father, ~] - [predicate, is, null] - [person, ~, father] - - [ person, ~, father ] - [ predicate, is, null ] - [ person, ~, son ] - [ relation, father, ~ ]- name: test patterns: - - [person, ~, person] - [ predicate, is, null ] - ['@person', ~, ttt]
在以上的模板规则中,对于每一个模板规则,需要指定其名字(name)及相应的模板(patterns)。
由于存在多个相近但不相同的模板对应同一种意图及词槽,所以这里的patterns是一个列表。
在以上的pattern.yml文件中,包含一个'@person'
,这里可以映射到person这个类别所对应的所有别名,具体来说,可以对应到["人物"]
列表中的所有词汇。
示例如下:
# -*- coding: utf-8 -*-import osimport sysproject_path = os.path.abspath(os.path.join(__file__, "../.."))sys.path.insert(0, project_path)from lightnlu.core import NER, Ruleif __name__ == '__main__': path = os.path.join(project_path, 'data/words.yml') ner = NER() ner.build_from_yml(path, base_dir=project_path) print(ner.entities) path = os.path.join(project_path, 'data/pattern.yml') rule = Rule() rule.build_from_yml(path) @rule.bind(rule_name="father_son_relation", act_name="test") def test(father: str, son: str): return { "father": father, "son": son } @rule.bind(rule_name="test", act_name="ppp") def ppp(person: str, ttt: str): return { "person": person, "ttt": ttt } print(rule.actors) text = "刘备和诸葛亮在新野旅游,途中遇上了曹操" slots = ner.extract(text) print(slots) print(rule.match(slots)) text = "曹丕的父亲是曹操" slots = ner.extract(text) print(rule.match(slots)) print(rule.match_and_act(slots)) text = "曹操是曹丕的父亲" slots = ner.extract(text) print(rule.match(slots)) print(rule.match_and_act(slots)) text = "曹操是个人物" slots = ner.extract(text) print(rule.match(slots)) print(rule.match_and_act(slots))
执行结果如下:
defaultdict(<function default_type at 0x7f88a96b00d0>, {'曹操': [{'type': 'person', 'id': '1'}], '刘备': [{'type': 'person', 'id': '2'}], '诸葛亮': [{'type': 'person', 'id': '3'}], '曹丕': [{'type': 'person', 'id': '4'}], '曹植': [{'type': 'person', 'id': '5'}], '人物': [{'type': '@person', 'id': None}], '洛阳': [{'type': 'place', 'id': '1'}], '长安': [{'type': 'place', 'id': '2'}], '新野': [{'type': 'place', 'id': '3'}], '赤壁': [{'type': 'place', 'id': '4'}], '宛城': [{'type': 'place', 'id': '5'}], '地点': [{'type': '@place', 'id': None}], '位置': [{'type': '@place', 'id': None}], '城市': [{'type': '@place', 'id': None}], '区域': [{'type': '@place', 'id': None}], '电站': [{'type': 'ban_words', 'id': ''}], '正在站': [{'type': 'ban_words', 'id': ''}], '引流线': [{'type': 'ban_words', 'id': ''}], '子导线': [{'type': 'ban_words', 'id': ''}], '甲母线': [{'type': 'ban_words', 'id': ''}], '规则': [{'type': '@ban_words', 'id': None}], '所属厂站': [{'type': 'attr', 'id': 'attr_ST_ID'}], '所属电厂': [{'type': 'attr', 'id': 'attr_ST_ID'}], '属于哪个厂站': [{'type': 'attr', 'id': 'attr_ST_ID'}], '属于哪个电厂': [{'type': 'attr', 'id': 'attr_ST_ID'}], '电压等级': [{'type': 'attr', 'id': 'attr_VOLTAGE_TYPE'}], '儿子': [{'type': 'relation', 'id': 'son'}], '父亲': [{'type': 'relation', 'id': 'father'}], '爸爸': [{'type': 'relation', 'id': 'father'}], '是': [{'type': 'predicate', 'id': 'is'}], '为': [{'type': 'predicate', 'id': 'is'}], '不是': [{'type': 'predicate', 'id': 'isnot'}], '不为': [{'type': 'predicate', 'id': 'isnot'}]})defaultdict(<class 'dict'>, {'father_son_relation': {'test': <function test at 0x7f88a967e940>}, 'test': {'ppp': <function ppp at 0x7f88a967e9d0>}})[('刘备', {'type': 'person', 'id': '2'}, 0, 2), ('诸葛亮', {'type': 'person', 'id': '3'}, 3, 6), ('新野', {'type': 'place', 'id': '3'}, 7, 9), ('曹操', {'type': 'person', 'id': '1'}, 17, 19)][][{'name': 'father_son_relation', 'slots': {'son': '曹丕', 'father': '曹操'}}]{'father_son_relation': {'test': {'father': '曹操', 'son': '曹丕'}}}[{'name': 'father_son_relation', 'slots': {'father': '曹操', 'son': '曹丕'}}]{'father_son_relation': {'test': {'father': '曹操', 'son': '曹丕'}}}[{'name': 'test', 'slots': {'person': '曹操', 'ttt': '人物'}}]{'test': {'ppp': {'person': '曹操', 'ttt': '人物'}}}
以下为部分创建Ubuntu容器的注意事项:
执行apt install tzdata
命令,安装完成后,即可设置区时,首先设置洲为Asia(亚洲),然后设置城市为Shanghai(70,上海)。
apt clean && apt autoclean && apt autoremove
现在想来,大致使用Python配置变量或配置文件的策略有以下几种:
其中各种选择各有利弊,具体在项目中如何使用需要具体情况具体分析。
今天重构项目觉得可以为flask项目各接口添加统一的前缀,而不是全部都是字符串拼接。
其中代码大致如下:
from flask import Flask, request, jsonify, send_filefrom flask_cors import CORSfrom werkzeug.routing import Rulefrom werkzeug.serving import run_simplefrom werkzeug.middleware.dispatcher import DispatcherMiddlewarePREFIX_PATH = "/prefix"HOST = "127.0.0.1"PORT = 8501if __name__ == '__main__': app = Flask(__name__) @app.route("/hello_world", methods=['POST', 'GET']) def hello_world(): return jsonify({ 'text': "Hello World!" }) application = DispatcherMiddleware(app, {PREFIX_PATH: app}) run_simple(HOST, PORT, application, use_debugger=False, threaded=True)
具体内容参见:FindCaller() takes from 1 to 2 positional arguments but 3 were given错误纠正_Mrchuncui的博客-CSDN博客,经过几番尝试之后,最终还是通过将python3.7版本的logging模块替换掉3.8版本的logging模块才得以解决。
]]>Jupyter大法好!
jupyter notebook --generate-config
使用以上命令得到notebook的配置文件,路径为:~/.jupyter/jupyter_notebook_config.py
,然后我们可以在其中修改是否允许以root用户启动,以及启动目录等。
需要借助almond
工具,首先需要先安装almond
,如下:
curl -Lo coursier https://git.io/coursier-clichmod +x coursier
然后执行如下命令安装:
./coursier launch --fork almond -- --install
或者是指定almond或scala版本:
./coursier launch --fork almond:0.10.0 --scala 2.13 -- --install
注释:使用
scala -version
命令查看scala版本。
以上的安装需要耗费一些时间,如果安装过程最后的输出信息为Installed scala kernel under /root/.local/share/jupyter/kernels/scala
,则说明安装成功。
这里的kernel更准确的来说应该是pyspark kernel。
安装命令如下:
pip install spylon-kernelpython -m spylon_kernel install
如下图,为scala kernel:
如下图,为spark kernel:
如下图,为jupyter notebook的所有kernels:
jupyter kernelspec list Available kernels: scala /root/.local/share/jupyter/kernels/scala python3 /opt/miniconda3/share/jupyter/kernels/python3 spylon-kernel /usr/local/share/jupyter/kernels/spylon-kernel
jupyter kernelspec remove <kernel-name>
首先使用jupyter kernelspec list
找到kernel所在的位置,然后在该文件夹下编辑kernel.json
文件,修改display_name
属性即可。
大爱VS Code~
]]>在安装spark之前,我们首先需要安装好以下几个组件:
关于java的安装,可以选择java8或者java11。使用以下命令搜索相关yum源程序:
yum search java
如下图:
之后可以使用如下命令安装java:
yum install java-1.8.0-openjdk-devel.x86_64
或
yum install java-11-openjdk-devel.x86_64
关于安装hadoop,之前已经写过相关文章如CentOS安装Hadoop - lightsmile’s Blog。关于hadoop的下载,我们可以通过清华源来下载,具体下载地址为:Index of /apache/hadoop/core/hadoop-3.3.0。
需要注意的是设置ssh免密登录过程可能会出现问题,在设置完成后可能还需要提示输入密码才可以。
这时可以输入:
ssh -vvv localhost
查看详细的登录日志信息,以确定问题所在。其中的问题主要包括~/.ssh
文件夹的权限不对以及authorized_keys
的权限不对,以及用户自定义ssh秘钥文件名等等。
可以输入以下命令以修改ssh文件夹权限:
chmod 700 ~/.ssh
chmod 0600 authorized_keys
如果用户不将ssh秘钥文件设置为默认的id_dsa或id_rsa等,那么用户还需要在~/.ssh文件夹下新增一个config文件以配置相关信息,具体内容大致如下:
Host localhost HostName localhost User hadoop Port 22 PreferredAuthentications publickey IdentityFile ~/.ssh/id_rsa
其中Host后面的localhost是指用户自定义的主机名,用于之后免密登录时ssh后面的地址,HostName则为实际的主机名,User指用户名,Port指ssh登录所使用的端口,IdentityFile指秘钥所对应的路径。
在新增config文件之后,同时也还需要设置该文件的权限,如:
chmod 0600 config
首先需要到ScalaDownload | The Scala Programming Language官网下载scala,可以下载如下文件:
在下载完成之后,将其解压到合适的文件夹,并将bin目录添加到系统PATH环境变量中即可。
我是将hadoop、spark和scala都放到了/opt路径下,同时新增了/etc/profile.d/hadoop.sh
文件,里面内容为:
export JAVA_HOME=/usr/lib/jvm/java-11-openjdk-11.0.9.11-3.el8_3.x86_64 export HADOOP_HOME=/opt/hadoop-3.3.0export SCALA_HOME=/opt/scala-2.13.4export SPARK_HOME=/opt/spark-3.0.1export PATH=$PATH:$HADOOP_HOME/bin:$HADOOP_HOME/sbin:$SCALA_HOME/bin:$SPARK_HOME/bin
安装完成之后,可以简单验证一下,如下图:
对于spark的下载,可以通过国内清华源下载以提高下载速度。具体网址为:Index of /apache/spark,当前最新版本的下载链接为:spark-3.0.1-bin-hadoop3.2.tgz。
在下载好spark后,解压到合适的位置并配置环境变量与配置scala类似,此处不表。在安装完成之后,可以简单验证一下,如下命令:
(base) ➜ ~ run-example SparkPi 10 2>&1 | grep "Pi is"Pi is roughly 3.144179144179144
通过以下命令排查得到java所对应端口:
(base) ➜ ~ netstat -tunlp | grep javatcp 0 0 0.0.0.0:8030 0.0.0.0:* LISTEN 81914/java tcp 0 0 0.0.0.0:8031 0.0.0.0:* LISTEN 81914/java tcp 0 0 0.0.0.0:8032 0.0.0.0:* LISTEN 81914/java tcp 0 0 0.0.0.0:8033 0.0.0.0:* LISTEN 81914/java tcp 0 0 0.0.0.0:8040 0.0.0.0:* LISTEN 82046/java tcp 0 0 127.0.0.1:9000 0.0.0.0:* LISTEN 81255/java tcp 0 0 0.0.0.0:8042 0.0.0.0:* LISTEN 82046/java tcp 0 0 0.0.0.0:9868 0.0.0.0:* LISTEN 81632/java tcp 0 0 0.0.0.0:9870 0.0.0.0:* LISTEN 81255/java tcp 0 0 0.0.0.0:36563 0.0.0.0:* LISTEN 82046/java tcp 0 0 0.0.0.0:8088 0.0.0.0:* LISTEN 81914/java
通过jps命令查看java进程信息:
(base) ➜ ~ jps81632 SecondaryNameNode81255 NameNode81914 ResourceManager82046 NodeManager190765 Jps
然后根据对应的端口号配置安全组,如下图:
]]>htop
命令查看了一下进程,好家伙,CPU都被占满了,这是什么鬼?!并且怎么还跑着奇奇怪怪的不知道啥名字的程序?!此时心里一惊,坏了,不会被黑客入侵了吧。。。然后大概网上搜了一下,果然情况和参考中两篇链接几乎一致,淦!
我是昨天刚在服务器上配置的hadoop用户密码,结果今天就被入侵了,然而腾讯云也没有任何报警提示,我服了。偷袭我一个Linux新手?我大意了啊,没防住~
担心自己处理不好还是留下后门,于是乎只能把服务器上的数据拷贝到本地,然后再重装系统了。
哎,2020果然不顺,最后一天都是如此悲催,希望2021能有好运气和好收获吧。
处于项目需要,我们需要在elasticsearch中设置自定义的词典与停用词,这里简单说明下其配置方法。
自己这里是通过docker以及docker-compose的方式来使用的,直接使用elasticsearch的方法流程与之类似,可以看下面的参考。
项目目录结构大致如下:
(base) ➜ elasticsearch tree ..├── config│ ├── IKAnalyzer.cfg.xml│ ├── stopwords.dic│ └── userwords.dic├── docker-compose.yml└── Dockerfile1 directory, 5 files
Dockerfile
其中Dockerfile
中内容如下:
FROM elasticsearch:7.7.1RUN yes | ./bin/elasticsearch-plugin install https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v7.7.1/elasticsearch-analysis-ik-7.7.1.zip
docker-compose.yml
其中docker-compose.yml
中内容如下:
version: '3'services: es: image: elasticsearch-ik:7.7.1 container_name: elasticsearch network_mode: "host" environment: - discovery.type=single-node ports: - 9200:9200 - 9300:9300 volumes: - ./config/IKAnalyzer.cfg.xml:/usr/share/elasticsearch/config/analysis-ik/IKAnalyzer.cfg.xml - ./config/userwords.dic:/usr/share/elasticsearch/config/analysis-ik/userwords.dic - ./config/stopwords.dic:/usr/share/elasticsearch/config/analysis-ik/stopwords.dic
IKAnalyzer.cfg.xml
其中IKAnalyzer.cfg.xml
中内容如下:
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd"><properties> <comment>IK Analyzer 扩展配置</comment> <!--用户可以在这里配置自己的扩展字典 --> <entry key="ext_dict">userwords.dic</entry> <!--用户可以在这里配置自己的扩展停止词字典--> <entry key="ext_stopwords">stopwords.dic</entry> <!--用户可以在这里配置远程扩展字典 --> <!-- <entry key="remote_ext_dict">words_location</entry> --> <!--用户可以在这里配置远程扩展停止词字典--> <!-- <entry key="remote_ext_stopwords">words_location</entry> --></properties>
stopwords.dic
其中stopwords.dic
内容如下:
吃
userwords.dic
其中userwords.dic
内容如下:
曹操和李德方
docker-compose up -d
效果如图:
可以看到,里面李德方
、曹操和
分别作为词语被拆分出来,同时吃
这个词直接就被过滤掉了。
于是乎决定只能在原来的服务器上做标注,考虑到持续使用,所以打算用tmux。没想到直接tmux报错,tmux报can't create socket
的错误,yum提示could not resolve host: mirrors.tencentyun.com; unknown error
的错误,更可怕的是ping 外网都ping不通。
后来参考腾讯云服务器 “Could not resolve host: mirrors.tencentyun.com; Unknown error” - 简书、mirrors.tencentyun.com 又挂了!_BLUEHEART-CSDN博客以及CentOS修改各大yum源(centos5,centos6,centos7) - 云+社区 - 腾讯云对yum源进行了配置,如:
cd /etc/yum.repos.dmv CentOS-Base.repo CentOS-Base.repo.backupwget -O CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repoyum clean allyum makecacheyum update
以及修改了/etc/yum.repos.d/CentOS-Epel.repo
文件,如下:
[epel]name=EPEL for redhat/centos $releasever - $basearchfailovermethod=prioritygpgcheck=1gpgkey=http://mirrors.163.com/epel/RPM-GPG-KEY-EPEL-7enabled=0baseurl=http://mirrors.163.com/epel/$releasever/$basearch/
然后解决了yum问题。
没想到tmux还是不行,后来找到了tmux can’t create socket: Permission denied · Issue #28 · MachinaCore/CygwinPortable通过在zshrc中配置alias tmux='tmux -S ~/.tmsock new -ADsCyg'
暂时解决了这个问题。
安装pipdeptree:
PS D:\test> pip install pipdeptree
假如想在内网安装flask,先在外网下载安装:
PS D:\test> pip install flask
使用pipdeptree 查看并生成requirements.txt
PS D:\test> pipdeptree -f -p flaskFlask==1.1.2 click==7.1.2 itsdangerous==1.1.0 Jinja2==2.11.2 MarkupSafe==1.1.1 Werkzeug==1.0.1PS D:\test> pipdeptree -f -p flask > .\requirements.txt
下载所有包至本地
PS D:\test> pip download -r .\requirements.txt
将test文件夹拷贝至内网机器(如F:/test),进入test目录执行如下命令离线安装
PS F:\test> pip install --no-index --find-links=./ -r requirements.txt
]]>关于Python开发,对我个人而言目前来说Pycharm专业版占主体,VSCode用于轻量开发场景。
关于Pycharm的破解使用,最开始是网上找的博客教程里面提到的免费的破解码,后来是通过淘宝购买的公用教育邮箱的法子,不过今天终于下决心决定支持正版了。
关于Pycharm,目前个人理解是自己这几年里使用这个工具收获良多,心怀感激之情,所以也应该为信仰充值,一如在Steam上购买正版游戏一样。
另外,其实JetBrains的产品也不算太贵,通过数码荔枝渠道:PyCharm: JetBrains 专业级Python IDE - 荔枝软件商店单购买Pycharm目前一年只需要569,并且可以永久使用该版本。
实在不想花这份钱的也可以选择通过开源项目申请的方式,具体可以参考:免费获取JetBrains全家桶正版License教程!! - 知乎
]]>