用 ansible 来创建 k8s,这类项目已经很多了,在 github 上面随意可以搜到很多,而这篇文章主要介绍的是如果用 ansible 来做日常的 k8s 运维和开发部署。
本文中的例子可以在 https://github.com/u2takey/ansible-k8s 找到
从我第一次使用 helm 就觉得这个东西的设计实在古怪:
后来出现了 kustomize,kustomize的设计并不依赖服务端,而是想做好本地渲染,然而几次使用之后发现,kustomize 显然还是失败了
关于运维和部署,ansible已经积累了太多经验,虽然本质上 ansible 最初的设计还是针对 "hosts", 并不是针对集群,ansible的 k8s module 质量也参差不齐,但是尽管如此,使用时候你会发现,ansible 在运维 k8s 的能力上还是很强。
这部分不是本文的重点,ansible 部署 k8s 是比较常见的 k8s 部署方式,这里给几个 star 比较高的项目,不再细述。
ansible 主要可以使用 k8s 模块来管理 k8s 资源
比如创建一个 namespace,可以使用下面的写法
- name: Create a k8s namespace
k8s:
name: testing
api_version: v1
kind: Namespace
state: present
创建 service 的写法
- name: Create a Service object from an inline definition
k8s:
state: present
definition:
apiVersion: v1
kind: Service
metadata:
name: web
namespace: testing
labels:
app: galaxy
service: web
spec:
selector:
app: galaxy
service: web
ports:
- protocol: TCP
targetPort: 8000
name: port-8000-tcp
port: 8000
上面的这种 inline 的写法实际上可读性比较差,更推荐使用 src(读取文件) 或者 definition + lookup + template 语句的办法来创建资源,ansible 的 template 使用 jinja2 来渲染,表达能力很强。
- name: Create a Deployment by reading the definition from a local file
k8s:
state: present
src: /testing/deployment.yml
- name: Read definition file from the Ansible controller file system after Jinja templating
k8s:
state: present
definition: "{{ lookup('template', '/testing/deployment.yml.j2') }}"
下面我们看一个完整的例子,这个例子里面我们有两个集群,分别叫 4lr4c3wx
和 8keawqnz
, 并且我们在本地的 admin.conf 里面加入了这两个 context, 所以我们不用在 ansible config里面添加相关密钥信息。
ansible-galaxy
初始化 role➜ ansible-galaxy role init nginx
➜ ll nginx
.rw-r--r-- 1.3k leiwang 4 Jan 15:11 README.md
drwxr-xr-x - leiwang 4 Jan 15:11 defaults
drwxr-xr-x - leiwang 4 Jan 15:11 files
drwxr-xr-x - leiwang 4 Jan 15:11 handlers
drwxr-xr-x - leiwang 4 Jan 15:11 meta
drwxr-xr-x - leiwang 4 Jan 15:11 tasks
drwxr-xr-x - leiwang 4 Jan 15:13 templates
drwxr-xr-x - leiwang 4 Jan 15:11 tests
drwxr-xr-x - leiwang 4 Jan 15:11 vars
# ansible.cfg
[defaults]
inventory = hosts.ini
host_key_checking = False
pipelining = True
gathering = smart
fact_caching = jsonfile
fact_caching_timeout = 86400
fact_caching_connection = /tmp/ansible_fact_cache
forks = 20
# host
[test]
4lr4c3wx context=4lr4c3wx
8keawqnz context=8keawqnz
[test:vars]
ansible_connection=local
ansible_python_interpreter=~/miniconda3/bin/python
ignore_errors
, 因为创建或者删除 namespace 时可能会报错,我们希望忽略这种错误。---
- debug: var=context
- name: set namespace {{ namespace }} to {{ state }}
k8s:
context: "{{ context }}"
api_version: v1
kind: Namespace
name: "{{ namespace }}"
state: "{{ state }}"
ignore_errors: true
- name: set nginx deployment to {{ state }}
k8s:
context: "{{ context }}"
state: "{{ state }}"
definition: "{{ lookup('template', 'nginx.yml.j2') | from_yaml_all | list }}"
namespace: "{{ namespace }}"
from_yaml_all
+ list
filter来处理apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: nginx
namespace: {{ namespace }}
labels:
version: v2
spec:
# 略
---
apiVersion: v1
kind: Service
metadata:
name: nginx
namespace: {{ namespace }}
spec:
# 略
---
- name: example k8s playbook
hosts: test
vars:
namespace: default
roles:
- nginx
➜ ansible-playbook main.yml
PLAY [example k8s playbook] *********************************************************************************************************************************************************
TASK [Gathering Facts] **************************************************************************************************************************************************************
ok: [test_cluster_2]
ok: [test_cluster_1]
TASK [nginx : debug] ****************************************************************************************************************************************************************
ok: [test_cluster_1] => {
"context": "4lr4c3wx"
}
ok: [test_cluster_2] => {
"context": "8keawqnz"
}
TASK [nginx : set namespace default to present] *************************************************************************************************************************************
ok: [test_cluster_1]
ok: [test_cluster_2]
TASK [nginx : set nginx deployment to present] **************************************************************************************************************************************
changed: [test_cluster_1]
changed: [test_cluster_2]
PLAY RECAP **************************************************************************************************************************************************************************
test_cluster_1 : ok=4 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
test_cluster_2 : ok=4 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
state=absent
清理刚刚创建的资源➜ ansible-playbook main.yml -e "state=absent"
这个完整的例子里面,我们创建一个 crd Nginx
, 这个Nginx 对应了一个 Nginx deployment和 一个service
cpu
, memory
, replicas
, 下面是这个 crd object的例子apiVersion: nginx.operator.t.io/v1
kind: Nginx
metadata:
name: example-nginx
spec:
# Add fields here
replicas: 3
cpu: 100m
memory: 100M
---
- name: nginx deployment
k8s:
definition: "{{ lookup('template', 'nginx-deployment.yml.j2') }}"
namespace: "{{ meta.namespace }}"
- name: nginx service
k8s:
definition: "{{ lookup('template', 'nginx-service.yml.j2') }}"
namespace: "{{ meta.namespace }}"
# test.yml
---
- hosts: localhost
vars:
meta:
name: test-nginx
namespace: default
roles:
- nginx
# do test
ansible-playbook test.yml
➜ sed -i 's|{{ REPLACE_IMAGE }}|ccr.ccs.tencentyun.com/mla-library/tool:test|g' deploy/operator.yaml
➜ sed -i 's|{{ pull_policy\|default('\''Always'\'') }}|Always|g' deploy/operator.yaml
➜ operator-sdk build ccr.ccs.tencentyun.com/mla-library/tool:test
➜ docker push ccr.ccs.tencentyun.com/mla-library/tool:test
Nginx
的创建情况(我们刚刚已经把 exampleNginx一并创建了),可以发现 deployment 和 service都符合预期原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。