쿠베르네트스 녹 방지제
지도 원칙
그 지도 원칙은 Kubernetes 컨트롤러를 만들어 기중기의 생명 주기를 감시하고 그 안에 사이드카를 주입하는 것이다.쿠베르네트스가 기중기를 조정할 때 컨트롤러가 옆차를 조정한다.전자를 삭제할 때도 후자를 삭제한다.
나는 상자를 열면 바로 사용할 수 있다는 것을 알고 있지만, 이것은 매우 좋은 학습 연습이다.그래서 저는 다음과 같은 몇 가지 절차를 통해 개발을 진행했습니다.
최초의 자바 프로젝트는 더 많은 절차를 사용했지만 본문과는 무관합니다.
준입 제어원 프로젝트 작성
이 프로젝트는 내 인생의 첫 번째 프로젝트이다. 나는 반드시 처음부터 프로젝트를 세워야 한다.내 이전의 모든 일은 아니면used an existing project이었다.
사용
cargo
:cargo new rust-operator # 1
rust-operator
에서 사용할 수 있습니다.rust-operator/
├── Cargo.toml
└── src
└── main.rs
다음을 포함합니다.[package]
name = "rust-operator" # 1
version = "0.1.0"
authors = ["Nicolas Frankel <[email protected]>"] # 2
edition = "2018" # 3
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] # 4
fn main() {
println!("Hello, world!");
}
이제 다음을 수행할 수 있습니다.빌드 패키지
cargo b
그리고 그것을 실행합니다
target/debug/rust-operator
Hello, world!
제공된 템플릿 복사 로그인 중
우선, 우리는 로그 레벨 (디버깅, 정보 등) 을 가진 라이브러리로 상자를 열 때 사용하는 로그 매크로를 대체할 것입니다.
몇 가지 연구를 통해 나는 판자 상자를 발견했다.
log4rs is a highly configurable logging framework modeled after Java's Logback and log4j libraries.
Rust library 생태계에 대한 이해가 부족한 점을 감안하여 저는
cargo init
를 선택했습니다. 왜냐하면 디자인이 Log4J와 유사하기 때문입니다.log4rs
를 사용하려면 다음 두 가지 종속성을 추가해야 합니다.[dependencies]
log4rs = "1.0.0" # 1
log = "0.4.14" # 2
log4rs
는 경량급 로그 외관으로 log
를 실현이제 소스 파일의 로그 매크로를 대체할 수 있습니다.
use log::info;
use log4rs;
fn main() {
log4rs::init_file("log4rs.yml", Default::default()).unwrap(); // 1
info!("Hello, world!"); // 2
}
log4rs
, 필요log4rs
파일log4rs.yml
파일의 내용에 달려 있습니다.내 견본으로 인쇄하기2021-07-05T16:26:16.041150+02:00 INFO rust_operator - Hello, world!
log4rs Rust에서 Kubernetes API 호출
일지 기록에 관해서 나는 반드시 도서관을 수색해야 한다.나의 기준은 매우 간단하다. 너무 저급하지 마라. 그래서 나는 HTTP 호출을 처리할 필요가 없지만, 너무 고급스럽지 않다. 그래서 나는 어떤 일도 할 필요가 없다.마지막으로 저는 :
Crate for interacting with the Kubernetes API
This crate includes the tools for manipulating Kubernetes resources as well as keeping track of those resources as they change over time
또한 개방형 API 사양에서 생성된 녹 자국을 결합해야 합니다.
[dependencies]
kube = "0.52.0"
k8s-openapi = { version = "0.11.0", default-features = false,
features = ["v1_19"] } # 1
log4rs.yml
입니다.kube
Client
를 얻으려면 가장 간단한 방법Client
을 사용해야 한다.Java 코드와 같이Will use
Config::infer
to try in-cluster environment variables first, then fallback to the local kubeconfig.Will fail if neither configuration could be loaded.
비동기 호출
똑똑한 독자들은 위의 그림
Client::try_default()
의 판에 박힌 인상을 이미 알아차렸을 것이다.각각 <<async>>
호출은 사실상 비동기적이다.Rust는 Client
trait, Future
/async
문법과 await
판자 상자를 통해 비동기성을 지원한다.다음 중 하나를 시도해 보겠습니다futures
:fn main() {
Client::try_default();
}
코드 세그먼트는 컴파일되지만 경고가 출력됩니다.warning: unused implementer of `futures::Future` that must be used
--> src/main.rs:14:5
|
14 | Client::try_default();
| ^^^^^^^^^^^^^^^^^^^^^^
|
= note: `#[warn(unused_must_use)]` on by default
= note: futures do nothing unless you `.await` or poll them
컴파일러가 주의한 바와 같이 aClient
자체는 아무것도 하지 않는다.그것을 사용하려면, 우리는 반드시 Future
그것을 사용해야 한다.fn main() {
Client::try_default().await;
}
이제 코드가 실패했습니다.error[E0728]: `await` is only allowed inside `async` functions and blocks
--> src/main.rs:14:18
|
12 | fn main() {
| ---- this is not `async`
13 | log4rs::init_file("log4rs.yml", Default::default()).unwrap();
14 | let client = Client::try_default().await;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ only allowed inside `async` functions and blocks
교훈은 다른 await
함수(와 블록)에서만 호출할 수 있음async
함수입니다.async
아니main
.가장 간단한 방법은 테이프
인데, 이것은 비동기 프로그래밍을 위한 판자 상자이다.Tokio는 async
비동기적인 매크로를 제공했다.#[tokio::main]
async fn main() {
Client::try_default().await;
}
마지막 단계는 열기main
에 포함된 Client
입니다.#[tokio::main]
async fn main() {
let client = Client::try_default().await.unwrap();
}
동경 콩꼬투리를 열거하다
이 점에서, 우리는 콩꼬투리를 열거하는 것과 같은 Kubernetes 집단과 상호작용을 할 수 있는
Result
을 얻었다.입구점은 범형Client
유형이고 그 중에서Api<K>
는 우리가 흥미를 느끼는 Kubernetes 대상이다.이제 작은 것부터 콩꼬투리를 열거해 봅시다.
K
는 Api::list()
파라미터가 필요합니다. 이 파라미터는 실현ListParams
됩니다.따라서 코드는 매우 간단합니다.
#[tokio::main]
async fn main() {
let api: Api<Pod> = Api::namespaced(client, "kube-system"); <1>
api.list(&ListParams::default())
.await
.unwrap()
.items
.iter()
.map(|pod| pod.name())
.for_each(|name| info!("{}", name));
}
Default
의 모든pods대상콩꼬투리를 보다
다음 단계는 크레인을 관찰하는 방법으로 옮기는 것이다.이를 위해, 우리는 매번 변경할 때마다 통지를 받을 수 있도록 손목시계를 등록해야 한다.네, 그게 문제예요.API는 매우 간단하지만 코드 자체는 결코 간단하지 않다.
#[tokio::main]
async fn main() {
let client = Client::try_default().await.unwrap();
let api: Api<Pod> = Api::namespaced(client, "kube-system");
let mut stream = api.watch(&ListParams::default(), "0") <1>
.await? <2>
.boxed(); <3>
while let Some(event) = stream
.try_next() <4>
.await? {
match event {
_ => {}
};
}
}
kube-system
호출watch()
Result
또는 반환 대기 Stream
Error
.본문을 쓸 때, 나는 찌르는 것에 대한 이해가 제로이기 때문에, 그것이 필요하고 효과가 있다고 가정한다.
Stream
의 다음 품목을 Stream
로 패키지Result
또는 반환WatchEvent
Error
:error[E0277]: the `?` operator can only be used in an async block that returns `Result` or `Option` (or another type that implements `Try`)
--> src/main.rs:12:22
|
8 | async fn main() {
| _________________-
9 | | let client = Client::try_default().await.unwrap();
10 | | let api: Api<Pod> = Api::namespaced(client, "kube-system");
11 | | let mut stream = api.watch(&ListParams::default(), "0").await?.boxed();
| | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot use the `?` operator in an async block that returns `()`
12 | | while let Some(event) = stream.try_next().await? {
13 | | }
14 | | }
| |_- this function should return `Result` or `Option` to accept `?`
|
= help: the trait `Try` is not implemented for `()`
= note: required by `from_error`
기억해라. await?
일반적인 값을 포함하거나, 실패를 포함하거나, 보통 Result
이다.Error
연산자는 ?
의 바로 가기입니다. 다음을 수행할 수 있습니다.현재 함수에서 실패
위의 코드 세그먼트에서
Result
함수는 어떤 반환 형식도 정의하지 않았습니다.컴파일 문제를 해결하려면 다음을 추가해야 합니다.#[tokio::main]
async fn main() -> Result<(), Error> { # 1
let client = Client::try_default().await.unwrap();
let api: Api<Pod> = Api::namespaced(client, "kube-system");
let mut stream = api.watch(&ListParams::default(), "0").await?.boxed();
while let Some(event) = stream.try_next().await? {
match event {
WatchEvent::Added(pod) => info!("ADDED: {}", pod.name()),
WatchEvent::Modified(pod) => info!("UPDATED: {}", pod.name()),
WatchEvent::Deleted(pod) => info!("DELETED: {}", pod.name()),
WatchEvent::Error(e) => error!("ERROR: {} {} ({})", e.code, e.message, e.status),
_ => {}
};
}
Ok(()) # 2
}
main()
반환 컨테이너화 컨트롤러
코드를 컨테이너화하기 위해 다단계 빌드를 사용합니다.
FROM ekidd/rust-musl-builder:1.51.0 as build
WORKDIR /app
COPY src src
COPY Cargo.lock .
COPY Cargo.toml .
RUN cargo build --release # 1
FROM scratch # 2
WORKDIR /app
COPY --from=build /app/target/x86_64-unknown-linux-musl/release/rust-operator /app
COPY log4rs.yml . # 3
CMD ["./rust-operator"]
Result
가능한 최소 크기REPOSITORY TAG IMAGE ID CREATED SIZE
rust-operator latest 5cac942d46a0 1 hour ago 18MB
결론
이 문서에서 Kubernetes 컨트롤러를 만드는 방법을 설명합니다.Rust의 의미는 다음과 같습니다.
이 글의 전체 소스 코드는 Github에서 찾을 수 있습니다.
/ 아자바지크
한 걸음 더 나아가 말하면:
Reference
이 문제에 관하여(쿠베르네트스 녹 방지제), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/nfrankel/a-rust-controller-for-kubernetes-15n1텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)